diff --git a/README.md b/README.md index e69de29..c8d5c75 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,4 @@ +# acme3k + +A small patch for [acme2k](https://github.com/karahobny/acme2k) that adds better background color support and a few other small changes. + diff --git a/acme3k.patch b/acme3k.patch new file mode 100644 index 0000000..58c7bb7 --- /dev/null +++ b/acme3k.patch @@ -0,0 +1,2281 @@ +diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c +index da24e706..28c429ec 100644 +--- a/src/cmd/acme/acme.c ++++ b/src/cmd/acme/acme.c +@@ -11,9 +11,11 @@ + #include + #include "dat.h" + #include "fns.h" +- /* for generating syms in mkfile only: */ +- #include +- #include "edit.h" ++#include "config.h" ++ ++/* for generating syms in mkfile only: */ ++#include ++#include "edit.h" + + void mousethread(void*); + void keyboardthread(void*); +@@ -21,28 +23,21 @@ void waitthread(void*); + void xfidallocthread(void*); + void newwindowthread(void*); + void plumbproc(void*); +-int timefmt(Fmt*); ++int timefmt(Fmt*); + + Reffont **fontcache; + int nfontcache; +-char wdir[512] = "."; ++char wdir[512] = "."; + Reffont *reffonts[2]; + int snarffd = -1; + int mainpid; +-int swapscrollbuttons = FALSE; +-char *mtpt; ++char *mtpt; + + enum{ + NSnarf = 1000 /* less than 1024, I/O buffer size */ + }; + Rune snarfrune[NSnarf+1]; + +-char *fontnames[2] = +-{ +- "/lib/font/bit/lucsans/euro.8.font", +- "/lib/font/bit/lucm/unicode.9.font" +-}; +- + Command *command; + + void shutdownthread(void*); +@@ -57,12 +52,6 @@ derror(Display *d, char *errorstr) + error(errorstr); + } + +-int +-threadmaybackground(void) +-{ +- return 1; +-} +- + void + threadmain(int argc, char *argv[]) + { +@@ -71,7 +60,6 @@ threadmain(int argc, char *argv[]) + Column *c; + int ncol; + Display *d; +- + rfork(RFENVG|RFNAMEG); + + ncol = -1; +@@ -84,11 +72,26 @@ threadmain(int argc, char *argv[]) + } + break; + case 'a': +- globalindent |= IndentAuto; ++ if(globalautoindent) ++ globalautoindent = FALSE; ++ else ++ globalautoindent = TRUE; + break; +- case 'b': ++ ++/* bartmode/flag is now an option to be turned on config.h, just ++ * because it is way too useful to leave it as an meaningless ++ * flag, especially since considering how almost everyone seems ++ * to even miss its existence. ++ * ++ * to get to the point, it denies window focus following mouse. ++ * how fickle those mice can truly be when decieveth by a soothing ++ * treat, a teat or two. ++ */ ++ ++/* case 'b': + bartflag = TRUE; +- break; ++ break; */ ++ + case 'c': + p = ARGF(); + if(p == nil) +@@ -107,9 +110,6 @@ threadmain(int argc, char *argv[]) + if(fontnames[1] == nil) + goto Usage; + break; +- case 'i': +- globalindent |= IndentSpaces; +- break; + case 'l': + loadfile = ARGF(); + if(loadfile == nil) +@@ -130,7 +130,7 @@ threadmain(int argc, char *argv[]) + break; + default: + Usage: +- fprint(2, "usage: acme -aibr -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); ++ fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); + threadexitsall("usage"); + }ARGEND + +@@ -392,7 +392,7 @@ int erroutfd; + void + acmeerrorproc(void *v) + { +- char *buf, *s; ++ char *buf; + int n; + + USED(v); +@@ -400,11 +400,8 @@ acmeerrorproc(void *v) + buf = emalloc(8192+1); + while((n=read(errorfd, buf, 8192)) >= 0){ + buf[n] = '\0'; +- s = estrdup(buf); +- sendp(cerr, s); +- free(s); ++ sendp(cerr, estrdup(buf)); + } +- free(buf); + } + + void +@@ -558,7 +555,7 @@ mousethread(void *v) + case MResize: + if(getwindow(display, Refnone) < 0) + error("attach to window"); +- draw(screen, screen->r, display->white, nil, ZP); ++ draw(screen, screen->r, tagcols[BACK], nil, ZP); + iconinit(); + scrlresize(); + rowresize(&row, screen->clipr); +@@ -626,10 +623,14 @@ mousethread(void *v) + goto Continue; + } + /* scroll buttons, wheels, etc. */ +- if(w != nil && m.scroll != 0){ ++ if(w != nil && (m.buttons & (8|16))){ ++ if(m.buttons & 8) ++ but = Kscrolloneup; ++ else ++ but = Kscrollonedown; + winlock(w, 'M'); + t->eq0 = ~0; +- textmomentumscroll(t, m.scroll); ++ texttype(t, but); + winunlock(w); + goto Continue; + } +@@ -971,74 +972,6 @@ Cursor boxcursor = { + 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00} + }; + +-Cursor2 boxcursor2 = { +- {-15, -15}, +- {0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xC0, 0x03, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF, +- 0xFF, 0xFF, 0xFF, 0xFF}, +- {0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0x00, 0x00, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x3F, 0xFF, 0xFF, 0xFC, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00} +-}; +- + void + iconinit(void) + { +@@ -1046,19 +979,19 @@ iconinit(void) + Image *tmp; + + if(tagcols[BACK] == nil) { +- /* Blue */ +- tagcols[BACK] = allocimagemix(display, DPalebluegreen, DWhite); +- tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen); +- tagcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue); +- tagcols[TEXT] = display->black; +- tagcols[HTEXT] = display->black; +- +- /* Yellow */ +- textcols[BACK] = allocimagemix(display, DPaleyellow, DWhite); +- textcols[HIGH] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow); +- textcols[BORD] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellowgreen); +- textcols[TEXT] = display->black; +- textcols[HTEXT] = display->black; ++ ++ tagcols[BACK] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TAGBG); ++ tagcols[HIGH] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TAGHLBG); ++ tagcols[BORD] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_COLBUTTON); ++ tagcols[TEXT] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TAGFG); ++ tagcols[HTEXT] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TAGHLFG); ++ ++ textcols[BACK] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TXTBG); ++ textcols[HIGH] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TXTHLBG); ++ textcols[BORD] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_SCROLLBG); ++ textcols[TEXT] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TXTFG); ++ textcols[HTEXT] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TXTHLFG); ++ + } + + r = Rect(0, 0, Scrollwid+ButtonBorder, font->height+1); +@@ -1082,15 +1015,15 @@ iconinit(void) + r.max.x -= ButtonBorder; + border(modbutton, r, ButtonBorder, tagcols[BORD], ZP); + r = insetrect(r, ButtonBorder); +- tmp = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedblue); ++ tmp = allocimage(display, Rect(0,0,1,1), RGBA32, 1, C_TMPBUTTON); + draw(modbutton, r, tmp, nil, ZP); + freeimage(tmp); + + r = button->r; +- colbutton = allocimage(display, r, screen->chan, 0, DPurpleblue); ++ colbutton = allocimage(display, r, RGBA32, 1, C_WINBUTTON); + +- but2col = allocimage(display, r, screen->chan, 1, 0xAA0000FF); +- but3col = allocimage(display, r, screen->chan, 1, 0x006600FF); ++ but2col = allocimage(display, r, screen->chan, 1, C_BUTTON2HL); ++ but3col = allocimage(display, r, screen->chan, 1, C_BUTTON3HL); + } + + /* +diff --git a/src/cmd/acme/addr.c b/src/cmd/acme/addr.c +index 6aee8993..2ccae960 100644 +--- a/src/cmd/acme/addr.c ++++ b/src/cmd/acme/addr.c +@@ -240,12 +240,12 @@ address(uint showerr, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, i + case '5': case '6': case '7': case '8': case '9': + n = c -'0'; + while(qwhite, nil, ZP); ++ draw(screen, r, textcols[BACK], nil, ZP); + c->r = r; + c->w = nil; + c->nw = 0; +@@ -89,19 +89,19 @@ coladd(Column *c, Window *w, Window *clone, int y) + /* + * figure out where to split v to make room for w + */ +- ++ + /* new window stops where next window begins */ + if(i < c->nw) + ymax = c->w[i]->r.min.y-Border; + else + ymax = c->r.max.y; +- ++ + /* new window must start after v's tag ends */ + y = max(y, v->tagtop.max.y+Border); +- ++ + /* new window must start early enough to end before ymax */ + y = min(y, ymax - minht); +- ++ + /* if y is too small, too many windows in column */ + if(y < v->tagtop.max.y+Border) + buggered = 1; +@@ -118,7 +118,7 @@ coladd(Column *c, Window *w, Window *clone, int y) + r1.min.y = winresize(v, r1, FALSE, FALSE); + r1.max.y = r1.min.y+Border; + draw(screen, r1, display->black, nil, ZP); +- ++ + /* + * leave r with w's coordinates + */ +@@ -142,7 +142,7 @@ coladd(Column *c, Window *w, Window *clone, int y) + c->nw++; + c->w[i] = w; + c->safe = TRUE; +- ++ + /* if there were too many windows, redraw the whole column */ + if(buggered) + colresize(c, c->r); +@@ -181,7 +181,7 @@ colclose(Column *c, Window *w, int dofree) + 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); ++ draw(screen, r, textcols[BACK], nil, ZP); + return; + } + up = 0; +@@ -232,7 +232,7 @@ colmousebut(Column *c) + void + colresize(Column *c, Rectangle r) + { +- int i, old, new; ++ int i; + Rectangle r1, r2; + Window *w; + +@@ -245,19 +245,13 @@ colresize(Column *c, Rectangle r) + r1.max.y += Border; + draw(screen, r1, display->black, nil, ZP); + r1.max.y = r.max.y; +- new = Dy(r) - c->nw*(Border + font->height); +- old = Dy(c->r) - c->nw*(Border + font->height); + for(i=0; inw; i++){ + w = c->w[i]; + w->maxlines = 0; + if(i == c->nw-1) + r1.max.y = r.max.y; +- else{ +- r1.max.y = r1.min.y; +- if(new > 0 && old > 0 && Dy(w->r) > Border+font->height){ +- r1.max.y += (Dy(w->r)-Border-font->height)*new/old + Border + font->height; +- } +- } ++ else ++ r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r); + r1.max.y = max(r1.max.y, r1.min.y + Border+font->height); + r2 = r1; + r2.max.y = r2.min.y+Border; +@@ -479,7 +473,7 @@ coldragwin(Column *c, Window *w, int but) + Column *nc; + + clearmouse(); +- setcursor2(mousectl, &boxcursor, &boxcursor2); ++ setcursor(mousectl, &boxcursor); + b = mouse->buttons; + op = mouse->xy; + while(mouse->buttons == b) +diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h +index 1dfc6a65..8c4b14ee 100644 +--- a/src/cmd/acme/dat.h ++++ b/src/cmd/acme/dat.h +@@ -198,13 +198,6 @@ struct Text + int needundo; + }; + +-enum +-{ +- /* default is tab indent, i.e. b'0 */ +- IndentSpaces = 0x1, +- IndentAuto = 0x2 +-}; +- + uint textbacknl(Text*, uint, uint); + uint textbsinsert(Text*, uint, Rune*, uint, int, int*); + int textbswidth(Text*, Rune); +@@ -234,7 +227,6 @@ int textselect3(Text*, uint*, uint*); + void textsetorigin(Text*, uint, int); + void textsetselect(Text*, uint, uint); + void textshow(Text*, uint, uint, int); +-void textmomentumscroll(Text*, int); + void texttype(Text*, Rune); + + struct Window +@@ -248,7 +240,7 @@ struct Window + uchar isscratch; + uchar filemenu; + uchar dirty; +- uchar indent; ++ uchar autoindent; + uchar showdel; + int id; + Range addr; +@@ -533,7 +525,6 @@ Image *button; + Image *but2col; + Image *but3col; + Cursor boxcursor; +-Cursor2 boxcursor2; + Row row; + int timerpid; + Disk *disk; +@@ -560,7 +551,7 @@ extern char wdir[]; /* must use extern because no dimension given */ + int editing; + int erroutfd; + int messagesize; /* negotiated in 9P version setup */ +-int globalindent; ++int globalautoindent; + int dodollarsigns; + char* mtpt; + +diff --git a/src/cmd/acme/ecmd.c b/src/cmd/acme/ecmd.c +index 357dd89f..ef92e339 100644 +--- a/src/cmd/acme/ecmd.c ++++ b/src/cmd/acme/ecmd.c +@@ -28,7 +28,7 @@ int append(File*, Cmd*, long); + int pdisplay(File*); + void pfilename(File*); + void looper(File*, Cmd*, int); +-void filelooper(Text*, Cmd*, int); ++void filelooper(Cmd*, int); + void linelooper(File*, Cmd*); + Address lineaddr(long, Address, int); + int filematch(File*, String*); +@@ -131,11 +131,14 @@ cmdexec(Text *t, Cmd *cp) + char* + edittext(Window *w, int q, Rune *r, int nr) + { ++ File *f; ++ ++ f = w->body.file; + switch(editing){ + case Inactive: + return "permission denied"; + case Inserting: +- eloginsert(w->body.file, q, r, nr); ++ eloginsert(f, q, r, nr); + return nil; + case Collecting: + collection = runerealloc(collection, ncollection+nr+1); +@@ -155,13 +158,11 @@ filelist(Text *t, Rune *r, int nr) + if(nr == 0) + return nil; + r = skipbl(r, nr, &nr); ++ if(r[0] != '<') ++ return runestrdup(r); ++ /* use < command to collect text */ + clearcollection(); +- if(r[0] != '<'){ +- if((collection = runestrdup(r)) != nil) +- ncollection += runestrlen(r); +- }else +- /* use < command to collect text */ +- runpipe(t, '<', r+1, nr-1, Collecting); ++ runpipe(t, '<', r+1, nr-1, Collecting); + return collection; + } + +@@ -583,7 +584,7 @@ X_cmd(Text *t, Cmd *cp) + { + USED(t); + +- filelooper(t, cp, cp->cmdc=='X'); ++ filelooper(cp, cp->cmdc=='X'); + return TRUE; + } + +@@ -632,8 +633,8 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state) + /* + * The editoutlk exists only so that we can tell when + * the editout file has been closed. It can get closed *after* +- * the process exits because, since the process cannot be +- * connected directly to editout (no 9P kernel support), ++ * the process exits because, since the process cannot be ++ * connected directly to editout (no 9P kernel support), + * the process is actually connected to a pipe to another + * process (arranged via 9pserve) that reads from the pipe + * and then writes the data in the pipe to editout using +@@ -703,7 +704,7 @@ printposn(Text *t, int mode) + + if (t != nil && t->file != nil && t->file->name != nil) + warning(nil, "%.*S:", t->file->nname, t->file->name); +- ++ + switch(mode) { + case PosnChars: + warning(nil, "#%d", addr.r.q0); +@@ -711,7 +712,7 @@ printposn(Text *t, int mode) + warning(nil, ",#%d", addr.r.q1); + warning(nil, "\n"); + return; +- ++ + default: + case PosnLine: + l1 = 1+nlcount(t, 0, addr.r.q0, nil); +@@ -977,10 +978,9 @@ alllocker(Window *w, void *v) + } + + void +-filelooper(Text *t, Cmd *cp, int XY) ++filelooper(Cmd *cp, int XY) + { + int i; +- Text *targ; + + if(Glooping++) + editerror("can't nest %c command", "YX"[XY]); +@@ -1001,26 +1001,8 @@ filelooper(Text *t, Cmd *cp, int XY) + */ + allwindows(alllocker, (void*)1); + globalincref = 1; +- +- /* +- * Unlock the window running the X command. +- * We'll need to lock and unlock each target window in turn. +- */ +- if(t && t->w) +- winunlock(t->w); +- +- for(i=0; ibody; +- if(targ && targ->w) +- winlock(targ->w, cp->cmdc); +- cmdexec(targ, cp->u.cmd); +- if(targ && targ->w) +- winunlock(targ->w); +- } +- +- if(t && t->w) +- winlock(t->w, cp->cmdc); +- ++ for(i=0; ibody, cp->u.cmd); + allwindows(alllocker, (void*)0); + globalincref = 0; + free(loopstruct.w); +diff --git a/src/cmd/acme/edit.c b/src/cmd/acme/edit.c +index 82a19b0d..d3f82059 100644 +--- a/src/cmd/acme/edit.c ++++ b/src/cmd/acme/edit.c +@@ -515,7 +515,7 @@ parsecmd(int nest) + if(nextc() == 'g') + cmd.flag = getch(); + } +- ++ + } + } + } +@@ -613,7 +613,7 @@ simpleaddr(void) + addr.num = getnum(1); + break; + case '0': case '1': case '2': case '3': case '4': +- case '5': case '6': case '7': case '8': case '9': ++ case '5': case '6': case '7': case '8': case '9': + addr.num = getnum(1); + addr.type='l'; + break; +@@ -635,11 +635,9 @@ simpleaddr(void) + case '.': + case '$': + case '\'': +- if(addr.type=='"') +- break; +- /* fall through */ ++ if(addr.type!='"') + case '"': +- editerror("bad address syntax"); ++ editerror("bad address syntax"); + break; + case 'l': + case '#': +diff --git a/src/cmd/acme/elog.c b/src/cmd/acme/elog.c +index 8a8951fb..c5650f03 100644 +--- a/src/cmd/acme/elog.c ++++ b/src/cmd/acme/elog.c +@@ -243,7 +243,7 @@ elogapply(File *f) + * but using coordinates relative to the unmodified buffer. As we apply the log, + * we have to update the coordinates to be relative to the modified buffer. + * Textinsert and textdelete will do this for us; our only work is to apply the +- * convention that an insertion at t->q0==t->q1 is intended to select the ++ * convention that an insertion at t->q0==t->q1 is intended to select the + * inserted text. + */ + +@@ -337,7 +337,7 @@ elogapply(File *f) + } + fbuffree(buf); + elogterm(f); +- ++ + /* + * Bad addresses will cause bufload to crash, so double check. + * If changes were out of order, we expect problems so don't complain further. +diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c +index 1c8083d8..deaef0cb 100644 +--- a/src/cmd/acme/exec.c ++++ b/src/cmd/acme/exec.c +@@ -109,7 +109,7 @@ Exectab exectab[] = { + { LGet, get, FALSE, TRUE, XXX }, + { LID, id, FALSE, XXX, XXX }, + { LIncl, incl, FALSE, XXX, XXX }, +- { LIndent, indent, FALSE, IndentAuto, XXX }, ++ { LIndent, indent, FALSE, XXX, XXX }, + { LKill, xkill, FALSE, XXX, XXX }, + { LLoad, dump, FALSE, FALSE, XXX }, + { LLocal, local, FALSE, XXX, XXX }, +@@ -192,9 +192,8 @@ execute(Text *t, uint aq0, uint aq1, int external, Text *argt) + f |= 2; + } + aa = getbytearg(argt, TRUE, TRUE, &a); +- if(a){ ++ if(a){ + if(strlen(a) > EVENTSIZE){ /* too big; too bad */ +- free(r); + free(aa); + free(a); + warning(nil, "argument string too long\n"); +@@ -674,7 +673,7 @@ checksha1(char *name, File *f, Dir *d) + DigestState *h; + uchar out[20]; + uchar *buf; +- ++ + fd = open(name, OREAD); + if(fd < 0) + return; +@@ -690,7 +689,7 @@ checksha1(char *name, File *f, Dir *d) + f->qidpath = d->qid.path; + f->mtime = d->mtime; + } +-} ++} + + void + putfile(File *f, int q0, int q1, Rune *namer, int nname) +@@ -699,7 +698,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + Rune *r; + Biobuf *b; + char *s, *name; +- int i, fd, q, ret, retc; ++ int i, fd, q; + Dir *d, *d1; + Window *w; + int isapp; +@@ -722,7 +721,6 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + goto Rescue1; + } + } +- + fd = create(name, OWRITE, 0666); + if(fd < 0){ + warning(nil, "can't create file %s: %r\n", name); +@@ -762,14 +760,9 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + warning(nil, "can't write file %s: %r\n", name); + goto Rescue2; + } +- ret = Bterm(b); +- retc = close(fd); ++ Bterm(b); + free(b); + b = nil; +- if(ret < 0 || retc < 0) { +- warning(nil, "can't write file %s: %r\n", name); +- goto Rescue2; // flush or close failed +- } + if(runeeq(namer, nname, f->name, f->nname)){ + if(q0!=0 || q1!=f->b.nc){ + f->mod = TRUE; +@@ -786,9 +779,10 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + // in case we don't have read permission. + // (The create above worked, so we probably + // still have write permission.) ++ close(fd); + fd = open(name, OWRITE); ++ + d1 = dirfstat(fd); +- close(fd); + if(d1 != nil){ + free(d); + d = d1; +@@ -821,11 +815,11 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + if(b != nil) { + Bterm(b); + free(b); +- close(fd); + } + free(h); + fbuffree(s); + fbuffree(r); ++ close(fd); + /* fall through */ + + Rescue1: +@@ -834,65 +828,6 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname) + free(name); + } + +-static void +-trimspaces(Text *et) +-{ +- File *f; +- Rune *r; +- Text *t; +- uint q0, n, delstart; +- int c, i, marked; +- +- t = &et->w->body; +- f = t->file; +- marked = 0; +- +- if(t->w!=nil && et->w!=t->w){ +- /* can this happen when t == &et->w->body? */ +- c = 'M'; +- if(et->w) +- c = et->w->owner; +- winlock(t->w, c); +- } +- +- r = fbufalloc(); +- q0 = f->b.nc; +- delstart = q0; /* end of current space run, or 0 if no active run; = q0 to delete spaces before EOF */ +- while(q0 > 0) { +- n = RBUFSIZE; +- if(n > q0) +- n = q0; +- q0 -= n; +- bufread(&f->b, q0, r, n); +- for(i=n; ; i--) { +- if(i == 0 || (r[i-1] != ' ' && r[i-1] != '\t')) { +- // Found non-space or start of buffer. Delete active space run. +- if(q0+i < delstart) { +- if(!marked) { +- marked = 1; +- seq++; +- filemark(f); +- } +- textdelete(t, q0+i, delstart, TRUE); +- } +- if(i == 0) { +- /* keep run active into tail of next buffer */ +- if(delstart > 0) +- delstart = q0; +- break; +- } +- delstart = 0; +- if(r[i-1] == '\n') +- delstart = q0+i-1; /* delete spaces before this newline */ +- } +- } +- } +- fbuffree(r); +- +- if(t->w!=nil && et->w!=t->w) +- winunlock(t->w); +-} +- + void + put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) + { +@@ -915,8 +850,6 @@ put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) + warning(nil, "no file name\n"); + return; + } +- if(w->indent & IndentAuto) +- trimspaces(et); + namer = bytetorune(name, &nname); + putfile(f, 0, f->b.nc, namer, nname); + xfidlog(w, "put"); +@@ -1387,59 +1320,37 @@ incl(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) + static Rune LON[] = { 'O', 'N', 0 }; + static Rune LOFF[] = { 'O', 'F', 'F', 0 }; + static Rune Lon[] = { 'o', 'n', 0 }; +-static Rune Loff[] = { 'o', 'f', 'f', 0 }; +- +-static Rune LTAB[] = { 'T', 'A', 'B', 0 }; +-static Rune LSPACE[] = { 'S', 'P', 'A', 'C', 'E', 0 }; +-static Rune Ltab[] = { 't', 'a', 'b', 0 }; +-static Rune Lspace[] = { 's', 'p', 'a', 'c', 'e', 0 }; + + enum { + IGlobal = -2, +- IError = -1 ++ IError = -1, ++ Ion = 0, ++ Ioff = 1 + }; + + static int +-indentval(Rune *s, int n, int windent) ++indentval(Rune *s, int n) + { + if(n < 2) + return IError; + if(runestrncmp(s, LON, n) == 0){ +- globalindent |= IndentAuto; ++ globalautoindent = TRUE; + warning(nil, "Indent ON\n"); + return IGlobal; + } + if(runestrncmp(s, LOFF, n) == 0){ +- globalindent &= ~IndentAuto; ++ globalautoindent = FALSE; + warning(nil, "Indent OFF\n"); + return IGlobal; + } +- if(runestrncmp(s, LTAB, n) == 0){ +- globalindent &= ~IndentSpaces; +- warning(nil, "Indent TAB\n"); +- return IGlobal; +- } +- if(runestrncmp(s, LSPACE, n) == 0){ +- globalindent |= IndentSpaces; +- warning(nil, "Indent SPACE\n"); +- return IGlobal; +- } +- if(runestrncmp(s, Lon, n) == 0) +- return windent | IndentAuto; +- if(runestrncmp(s, Loff, n) == 0) +- return windent & ~IndentAuto; +- if(runestrncmp(s, Ltab, n) == 0) +- return windent & ~IndentSpaces; +- if(runestrncmp(s, Lspace, n) == 0) +- return windent | IndentSpaces; +- return IError; ++ return runestrncmp(s, Lon, n) == 0; + } + + static void + fixindent(Window *w, void *arg) + { + USED(arg); +- w->indent = globalindent; ++ w->autoindent = globalautoindent; + } + + void +@@ -1447,7 +1358,7 @@ indent(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) + { + Rune *a, *r; + Window *w; +- int na, len, indent; ++ int na, len, autoindent; + + USED(_0); + USED(_1); +@@ -1456,19 +1367,19 @@ indent(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) + w = nil; + if(et!=nil && et->w!=nil) + w = et->w; +- indent = IError; ++ autoindent = IError; + getarg(argt, FALSE, TRUE, &r, &len); + if(r!=nil && len>0) +- indent = indentval(r, len, w->indent); ++ autoindent = indentval(r, len); + else{ + a = findbl(arg, narg, &na); + if(a != arg) +- indent = indentval(arg, narg-na, w->indent); ++ autoindent = indentval(arg, narg-na); + } +- if(indent == IGlobal) ++ if(autoindent == IGlobal) + allwindows(fixindent, nil); +- else if(w != nil && indent >= 0) +- w->indent = indent; ++ else if(w != nil && autoindent >= 0) ++ w->autoindent = autoindent; + } + + void +diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h +index c0339c23..8dc02378 100644 +--- a/src/cmd/acme/fns.h ++++ b/src/cmd/acme/fns.h +@@ -95,7 +95,6 @@ void flushwarnings(void); + void startplumbing(void); + long nlcount(Text*, long, long, long*); + long nlcounttopos(Text*, long, long, long); +-Rune* parsetag(Window*, int, int*); + + Runestr runestr(Rune*, uint); + Range range(int, int); +diff --git a/src/cmd/acme/fsys.c b/src/cmd/acme/fsys.c +index d9d4b30d..4c395eb2 100644 +--- a/src/cmd/acme/fsys.c ++++ b/src/cmd/acme/fsys.c +@@ -463,7 +463,7 @@ fsyswalk(Xfid *x, Fid *f) + qunlock(&row.lk); + dir = dirtabw; + goto Accept; +- ++ + Regular: + if(strcmp(x->fcall.wname[i], "new") == 0){ + if(w) +diff --git a/src/cmd/acme/logf.c b/src/cmd/acme/logf.c +index 562026c9..567b8383 100644 +--- a/src/cmd/acme/logf.c ++++ b/src/cmd/acme/logf.c +@@ -20,7 +20,7 @@ struct Log + Rendez r; + + vlong start; // msg[0] corresponds to 'start' in the global sequence of events +- ++ + // queued events (nev=entries in ev, mev=capacity of p) + char **ev; + int nev; +@@ -30,7 +30,7 @@ struct Log + Fid **f; + int nf; + int mf; +- ++ + // active (blocked) reads waiting for events + Xfid **read; + int nread; +@@ -43,7 +43,7 @@ void + xfidlogopen(Xfid *x) + { + qlock(&eventlog.lk); +- if(eventlog.nf >= eventlog.mf) { ++ if(eventlog.nf >= eventlog.mf) { + eventlog.mf = eventlog.mf*2; + if(eventlog.mf == 0) + eventlog.mf = 8; +@@ -78,20 +78,20 @@ xfidlogread(Xfid *x) + Fcall fc; + + qlock(&eventlog.lk); +- if(eventlog.nread >= eventlog.mread) { ++ if(eventlog.nread >= eventlog.mread) { + eventlog.mread = eventlog.mread*2; + if(eventlog.mread == 0) + eventlog.mread = 8; + eventlog.read = erealloc(eventlog.read, eventlog.mread*sizeof eventlog.read[0]); + } + eventlog.read[eventlog.nread++] = x; +- ++ + if(eventlog.r.l == nil) + eventlog.r.l = &eventlog.lk; + x->flushed = FALSE; + while(x->f->logoff >= eventlog.start+eventlog.nev && !x->flushed) + rsleep(&eventlog.r); +- ++ + for(i=0; i= eventlog.mev) { + eventlog.mev = eventlog.mev*2; +diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c +index 6e97e421..cbbc71bf 100644 +--- a/src/cmd/acme/look.c ++++ b/src/cmd/acme/look.c +@@ -30,7 +30,7 @@ plumbthread(void *v) + + USED(v); + threadsetname("plumbproc"); +- ++ + /* + * Loop so that if plumber is restarted, acme need not be. + */ +@@ -46,7 +46,7 @@ plumbthread(void *v) + } + plumbeditfid = fid; + plumbsendfid = plumbopenfid("send", OWRITE|OCEXEC); +- ++ + /* + * Relay messages. + */ +@@ -378,7 +378,7 @@ search(Text *ct, Rune *r, uint n) + int + isfilec(Rune r) + { +- static Rune Lx[] = { '.', '-', '+', '/', ':', '@', 0 }; ++ static Rune Lx[] = { '.', '-', '+', '/', ':', 0 }; + if(isalnum(r)) + return TRUE; + if(runestrchr(Lx, r)) +@@ -432,9 +432,9 @@ includename(Text *t, Rune *r, int n) + char buf[128]; + Rune Lsysinclude[] = { '/', 's', 'y', 's', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 }; + Rune Lusrinclude[] = { '/', 'u', 's', 'r', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 }; +- Rune Lusrlocalinclude[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', ++ Rune Lusrlocalinclude[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', + '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 }; +- Rune Lusrlocalplan9include[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', ++ Rune Lusrlocalplan9include[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', + '/', 'p', 'l', 'a', 'n', '9', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 }; + Runestr file; + int i; +@@ -443,7 +443,7 @@ includename(Text *t, Rune *r, int n) + sprint(buf, "/%s/include", objtype); + objdir = bytetorune(buf, &i); + objdir = runerealloc(objdir, i+1); +- objdir[i] = '\0'; ++ objdir[i] = '\0'; + } + + w = t->w; +@@ -477,9 +477,9 @@ includename(Text *t, Rune *r, int n) + Runestr + dirname(Text *t, Rune *r, int n) + { +- Rune *b; +- uint nt; +- int slash, i; ++ Rune *b, c; ++ uint m, nt; ++ int slash; + Runestr tmp; + + b = nil; +@@ -490,13 +490,15 @@ dirname(Text *t, Rune *r, int n) + goto Rescue; + if(n>=1 && r[0]=='/') + goto Rescue; +- b = parsetag(t->w, n, &i); ++ b = runemalloc(nt+n+1); ++ bufread(&t->w->tag.file->b, 0, b, nt); + slash = -1; +- for(i--; i >= 0; i--){ +- if(b[i] == '/'){ +- slash = i; ++ for(m=0; m= t->file->b.nc || textreadc(t, q0+i) != r[i]) +- return FALSE; +- return TRUE; +-} +- + int + expandfile(Text *t, uint q0, uint q1, Expand *e) + { +@@ -533,14 +522,12 @@ expandfile(Text *t, uint q0, uint q1, Expand *e) + Rune *r, c; + Window *w; + Runestr rs; +- Rune Lhttpcss[] = {'h', 't', 't', 'p', ':', '/', '/', 0}; +- Rune Lhttpscss[] = {'h', 't', 't', 'p', 's', ':', '/', '/', 0}; + + amax = q1; + if(q1 == q0){ + colon = -1; + while(q1file->b.nc && isfilec(c=textreadc(t, q1))){ +- if(c == ':' && !texthas(t, q1-4, Lhttpcss) && !texthas(t, q1-5, Lhttpscss)){ ++ if(c == ':'){ + colon = q1; + break; + } +@@ -548,7 +535,7 @@ expandfile(Text *t, uint q0, uint q1, Expand *e) + } + while(q0>0 && (isfilec(c=textreadc(t, q0-1)) || isaddrc(c) || isregexc(c))){ + q0--; +- if(colon<0 && c==':' && !texthas(t, q0-4, Lhttpcss) && !texthas(t, q0-5, Lhttpscss)) ++ if(colon<0 && c==':') + colon = q0; + } + /* +@@ -578,23 +565,8 @@ expandfile(Text *t, uint q0, uint q1, Expand *e) + if(n == 0) + return FALSE; + /* see if it's a file name */ +- r = runemalloc(n+1); ++ r = runemalloc(n); + bufread(&t->file->b, q0, r, n); +- r[n] = 0; +- /* is it a URL? look for http:// and https:// prefix */ +- if(runestrncmp(r, Lhttpcss, 7) == 0 || runestrncmp(r, Lhttpscss, 8) == 0){ +- // Avoid capturing end-of-sentence punctuation. +- if(r[n-1] == '.') { +- e->q1--; +- n--; +- } +- e->name = r; +- e->nname = n; +- e->u.at = t; +- e->a0 = e->q1; +- e->a1 = e->q1; +- return TRUE; +- } + /* first, does it have bad chars? */ + nname = -1; + for(i=0; i, and turn that into an include +@@ -756,7 +728,7 @@ openfile(Text *t, Expand *e) + /* + * Unrooted path in new window. + * This can happen if we type a pwd-relative path +- * in the topmost tag or the column tags. ++ * in the topmost tag or the column tags. + * Most of the time plumber takes care of these, + * but plumber might not be running or might not + * be configured to accept plumbed directories. +@@ -797,9 +769,9 @@ openfile(Text *t, Expand *e) + runemove(rp, ow->incl[i], n); + winaddincl(w, rp, n); + } +- w->indent = ow->indent; ++ w->autoindent = ow->autoindent; + }else +- w->indent = globalindent; ++ w->autoindent = globalautoindent; + xfidlog(w, "new"); + } + if(e->a1 == e->a0) +diff --git a/src/cmd/acme/mail/dat.h b/src/cmd/acme/mail/dat.h +index 66bb3a5d..a7ac6a0b 100644 +--- a/src/cmd/acme/mail/dat.h ++++ b/src/cmd/acme/mail/dat.h +@@ -178,3 +178,4 @@ extern int shortmenu; + + extern CFsys *mailfs; + extern CFsys *acmefs; ++ +diff --git a/src/cmd/acme/mail/html.c b/src/cmd/acme/mail/html.c +index e193fc4d..e3a956b0 100644 +--- a/src/cmd/acme/mail/html.c ++++ b/src/cmd/acme/mail/html.c +@@ -67,7 +67,7 @@ char* + readbody(char *type, char *dir, int *np) + { + char *body; +- ++ + body = readfile(dir, "body", np); + if(body != nil && strcmp(type, "text/html") == 0) + return formathtml(body, np); +diff --git a/src/cmd/acme/mail/mail.c b/src/cmd/acme/mail/mail.c +index e1047bb8..d79721f8 100644 +--- a/src/cmd/acme/mail/mail.c ++++ b/src/cmd/acme/mail/mail.c +@@ -558,16 +558,16 @@ mainctl(void *v) + Unknown: + print("unknown message %c%c\n", e->c1, e->c2); + break; +- ++ + case 'E': /* write to body; can't affect us */ + break; +- ++ + case 'F': /* generated by our actions; ignore */ + break; +- ++ + case 'K': /* type away; we don't care */ + break; +- ++ + case 'M': + switch(e->c2){ + case 'x': +@@ -597,7 +597,7 @@ mainctl(void *v) + if(na) + free(s); + break; +- ++ + case 'l': + case 'L': + buf = nil; +@@ -628,16 +628,17 @@ mainctl(void *v) + winwriteevent(w, e); + free(buf); + break; +- ++ + case 'I': /* modify away; we don't care */ + case 'D': + case 'd': + case 'i': + break; +- ++ + default: + goto Unknown; + } + } + } + } ++ +diff --git a/src/cmd/acme/mail/mesg.c b/src/cmd/acme/mail/mesg.c +index 739ce10a..9bfe10e1 100644 +--- a/src/cmd/acme/mail/mesg.c ++++ b/src/cmd/acme/mail/mesg.c +@@ -85,7 +85,7 @@ mkaddrs(char *t, char **colon) + int i, nf, inquote; + char **f, *s; + Fmt fmt; +- ++ + inquote = 0; + nf = 2; + for(s=t; *s; s++){ +@@ -127,7 +127,7 @@ loadinfo(Message *m, char *dir) + data = readfile(dir, "info", &n); + if(data == nil) + return 0; +- ++ + p = data; + while((s = line(p, &p)) != nil && *s != 0){ + t = strchr(s, ' '); +@@ -282,7 +282,7 @@ mesgadd(Message *mbox, char *dir, Dir *d, char *digest) + + if (m->level != 1){ + m->recursed = 1; +- readmbox(m, dir, m->name); ++ readmbox(m, dir, m->name); + } + return 1; + } +@@ -351,7 +351,7 @@ readfile(char *dir, char *name, int *np) + fsseek(fid, 0, 0); + free(d); + d = fsdirfstat(fid); +- } ++ } + free(file); + len = 0; + if(d != nil) +@@ -400,13 +400,13 @@ info(Message *m, int ind, int ogf) + i = estrdup(s); + + return i; +- } ++ } + + i = estrdup(""); + i = eappend(i, "\t", p); + i = egrow(i, "\t", stripdate(m->date)); + if(ind == 0){ +- if(strcmp(m->type, "text")!=0 && strncmp(m->type, "text/", 5)!=0 && ++ if(strcmp(m->type, "text")!=0 && strncmp(m->type, "text/", 5)!=0 && + strncmp(m->type, "multipart/", 10)!=0) + i = egrow(i, "\t(", estrstrdup(m->type, ")")); + }else if(strncmp(m->type, "multipart/", 10) != 0) +@@ -647,7 +647,7 @@ mesgsave(Message *m, char *s, int save) + } + return 1; + } +- ++ + t = estrstrdup(mbox.name, m->name); + raw = readfile(t, "raw", &n); + unixheader = readfile(t, "unixheader", &k); +@@ -1160,7 +1160,7 @@ tokenizec(char *str, char **args, int max, char *splitc) + + if(max <= 0) + return 0; +- ++ + /* if(strchr(str, ',') || strchr(str, '"') || strchr(str, '<') || strchr(str, '(')) */ + /* splitc = ","; */ + for(na=0; *str != '\0';str++){ +diff --git a/src/cmd/acme/mail/reply.c b/src/cmd/acme/mail/reply.c +index f28cbef1..5dda0edc 100644 +--- a/src/cmd/acme/mail/reply.c ++++ b/src/cmd/acme/mail/reply.c +@@ -78,7 +78,7 @@ mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext) + Plumbattr *a; + + quotereply = (label[0] == 'Q'); +- ++ + if(quotereply && m && m->replywinid > 0){ + snprint(buf, sizeof buf, "%d/body", m->replywinid); + if((fd = fsopen(acmefs, buf, OWRITE)) != nil){ +@@ -88,7 +88,7 @@ mkreply(Message *m, char *label, char *to, Plumbattr *attr, char *quotetext) + return; + } + } +- ++ + r = emalloc(sizeof(Message)); + r->isreply = 1; + if(m != nil) +@@ -212,7 +212,7 @@ execproc(void *v) + q[0] = e->q[0]; + q[1] = e->q[1]; + prog = e->prog; /* known not to be malloc'ed */ +- ++ + fd[0] = dup(p[0], -1); + if(q[0]) + fd[1] = dup(q[1], -1); +@@ -224,7 +224,7 @@ execproc(void *v) + free(e->argv); + chanfree(e->sync); + free(e); +- ++ + threadexec(nil, fd, prog, argv); + close(fd[0]); + close(fd[1]); +diff --git a/src/cmd/acme/mail/util.c b/src/cmd/acme/mail/util.c +index 8ac9f946..888e7e72 100644 +--- a/src/cmd/acme/mail/util.c ++++ b/src/cmd/acme/mail/util.c +@@ -104,3 +104,4 @@ ctlprint(CFid *fd, char *fmt, ...) + if(n <= 0) + error("control file write error: %r"); + } ++ +diff --git a/src/cmd/acme/mail/win.c b/src/cmd/acme/mail/win.c +index 1cf776dd..84c9cee0 100644 +--- a/src/cmd/acme/mail/win.c ++++ b/src/cmd/acme/mail/win.c +@@ -196,7 +196,7 @@ wingeter(Window *w, char *buf, int *nb) + while(!fullrune(buf, n)) + buf[n++] = wingetec(w); + chartorune(&r, buf); +- } ++ } + *nb = n; + return r; + } +diff --git a/src/cmd/acme/mkfile b/src/cmd/acme/mkfile +index 18bea9e0..2bad712c 100644 +--- a/src/cmd/acme/mkfile ++++ b/src/cmd/acme/mkfile +@@ -29,6 +29,7 @@ OFILES=\ + HFILES=dat.h\ + edit.h\ + fns.h\ ++ config.h + + <$PLAN9/src/mkone + <$PLAN9/src/mkdirs +diff --git a/src/cmd/acme/regx.c b/src/cmd/acme/regx.c +index ec574563..56ea900c 100644 +--- a/src/cmd/acme/regx.c ++++ b/src/cmd/acme/regx.c +@@ -15,9 +15,6 @@ + Rangeset sel; + Rune *lastregexp; + +-#undef class +-#define class regxclass /* some systems declare "class" in system headers */ +- + /* + * Machine Information + */ +diff --git a/src/cmd/acme/rows.c b/src/cmd/acme/rows.c +index 7a64fabf..8ed66266 100644 +--- a/src/cmd/acme/rows.c ++++ b/src/cmd/acme/rows.c +@@ -28,7 +28,7 @@ rowinit(Row *row, Rectangle r) + Rectangle r1; + Text *t; + +- draw(screen, r, display->white, nil, ZP); ++ draw(screen, r, textcols[BACK], nil, ZP); + row->r = r; + row->col = nil; + row->ncol = 0; +@@ -73,7 +73,7 @@ rowadd(Row *row, Column *c, int x) + r = d->r; + if(Dx(r) < 100) + return nil; +- draw(screen, r, display->white, nil, ZP); ++ draw(screen, r, textcols[BACK], nil, ZP); + r1 = r; + r1.max.x = min(x-Border, r.max.x-50); + if(Dx(r1) < 50) +@@ -148,7 +148,7 @@ rowdragcol(Row *row, Column *c, int _0) + USED(_0); + + clearmouse(); +- setcursor2(mousectl, &boxcursor, &boxcursor2); ++ setcursor(mousectl, &boxcursor); + b = mouse->buttons; + op = mouse->xy; + while(mouse->buttons == b) +@@ -191,7 +191,7 @@ rowdragcol(Row *row, Column *c, int _0) + p.x = c->r.max.x-80-Scrollwid; + r = d->r; + r.max.x = c->r.max.x; +- draw(screen, r, display->white, nil, ZP); ++ draw(screen, r, textcols[BACK], nil, ZP); + r.max.x = p.x; + colresize(d, r); + r = c->r; +@@ -223,7 +223,7 @@ rowclose(Row *row, Column *c, int dofree) + 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); ++ draw(screen, r, textcols[BACK], nil, ZP); + return; + } + if(i == row->ncol){ /* extend last column right */ +@@ -234,7 +234,7 @@ rowclose(Row *row, Column *c, int dofree) + c = row->col[i]; + r.max.x = c->r.max.x; + } +- draw(screen, r, display->white, nil, ZP); ++ draw(screen, r, textcols[BACK], nil, ZP); + colresize(c, r); + } + +@@ -316,7 +316,7 @@ rowclean(Row *row) + void + rowdump(Row *row, char *file) + { +- int i, j, fd, m, n, start, dumped; ++ int i, j, fd, m, n, dumped; + uint q0, q1; + Biobuf *b; + char *buf, *a, *fontname; +@@ -434,17 +434,9 @@ rowdump(Row *row, char *file) + m = min(RBUFSIZE, w->tag.file->b.nc); + bufread(&w->tag.file->b, 0, r, m); + n = 0; +- while(nfile->b.nc; +@@ -592,7 +584,7 @@ rowload(Row *row, char *file, int initing) + r2.min.x = x; + if(Dx(r1) < 50 || Dx(r2) < 50) + continue; +- draw(screen, Rpt(r1.min, r2.max), display->white, nil, ZP); ++ draw(screen, Rpt(r1.min, r2.max), textcols[BACK], nil, ZP); + colresize(c1, r1); + colresize(c2, r2); + r2.min.x = x-Border; +@@ -621,7 +613,6 @@ rowload(Row *row, char *file, int initing) + } + textdelete(&row->col[i]->tag, 0, row->col[i]->tag.file->b.nc, TRUE); + textinsert(&row->col[i]->tag, 0, r+n+1, nr-(n+1), TRUE); +- free(r); + break; + case 'w': + l[Blinelen(b)-1] = 0; +@@ -635,7 +626,6 @@ rowload(Row *row, char *file, int initing) + } + textdelete(&row->tag, 0, row->tag.file->b.nc, TRUE); + textinsert(&row->tag, 0, r, nr, TRUE); +- free(r); + break; + default: + done = 1; +@@ -727,10 +717,6 @@ rowload(Row *row, char *file, int initing) + if(l == nil) + goto Rescue2; + l[Blinelen(b)-1] = 0; +- /* convert 0xff in multiline tag back to \n */ +- for(i = 0; l[i] != 0; i++) +- if((uchar)l[i] == 0xff) +- l[i] = '\n'; + r = bytetorune(l+5*12, &nr); + ns = -1; + for(n=0; niq1) + t->iq1 += n; +@@ -532,27 +532,6 @@ textreadc(Text *t, uint q) + return r; + } + +-static int +-spacebswidth(Text *t) +-{ +- uint q, col; +- Rune r; +- +- col = textbswidth(t, 0x15); +- q = t->q0; +- while(q > 0){ +- r = textreadc(t, q-1); +- if(r != ' ') +- break; +- q--; +- if(--col % t->tabstop == 0) +- break; +- } +- if(t->q0 == q) +- return 1; +- return t->q0-q; +-} +- + int + textbswidth(Text *t, Rune c) + { +@@ -561,11 +540,8 @@ textbswidth(Text *t, Rune c) + int skipping; + + /* there is known to be at least one character to erase */ +- if(c == 0x08){ /* ^H: erase character */ +- if(t->what == Body && t->w->indent & IndentSpaces) +- return spacebswidth(t); ++ if(c == 0x08) /* ^H: erase character */ + return 1; +- } + q = t->q0; + skipping = TRUE; + while(q > 0){ +@@ -573,7 +549,7 @@ textbswidth(Text *t, Rune c) + if(r == '\n'){ /* eat at most one more character */ + if(q == t->q0) /* eat the newline */ + --q; +- break; ++ break; + } + if(c == 0x17){ + eq = isalnum(r); +@@ -688,32 +664,6 @@ textcomplete(Text *t) + return rp; + } + +-void +-textmomentumscroll(Text *t, int n) +-{ +- uint q0; +- +- if(n == 0) +- return; +- +- if(t->what == Tag){ +- if(n<0) +- texttype(t, Kscrolloneup); +- else +- texttype(t, Kscrollonedown); +- return; +- } +- +- if(n < 0){ +- n = -n; +- 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, TRUE); +- }else{ +- q0 = textbacknl(t, t->org, n); +- textsetorigin(t, q0, TRUE); +- } +-} +- + void + texttype(Text *t, Rune r) + { +@@ -741,11 +691,6 @@ texttype(Text *t, Rune r) + if(t->q1 < t->file->b.nc) + textshow(t, t->q1+1, t->q1+1, TRUE); + return; +- case Kdown: +- if(t->what == Tag) +- goto Tagdown; +- n = t->fr.maxlines/3; +- goto case_Down; + case Kscrollonedown: + if(t->what == Tag) + goto Tagdown; +@@ -758,12 +703,7 @@ texttype(Text *t, Rune r) + case_Down: + 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, TRUE); +- return; +- case Kup: +- if(t->what == Tag) +- goto Tagup; +- n = t->fr.maxlines/3; +- goto case_Up; ++ return; + case Kscrolloneup: + if(t->what == Tag) + goto Tagup; +@@ -775,27 +715,61 @@ texttype(Text *t, Rune r) + q0 = textbacknl(t, t->org, n); + textsetorigin(t, q0, TRUE); + return; +- case Khome: ++ ++/* ++ * Keybindings for moving the cursor up and ++ * down the text via up and down arrow keys. ++ */ ++ ++ case Kdown: ++ if(t->what == Tag) ++ goto Tagdown; + typecommit(t); +- if(t->org > t->iq1) { +- q0 = textbacknl(t, t->iq1, 1); +- textsetorigin(t, q0, TRUE); +- } else +- textshow(t, 0, 0, FALSE); ++ /* 1rst check for being in the last line*/ ++ q0 = t->q0; ++ q1 = q0; ++ if (q1) q1--; ++ nnb = 0; ++ while(q0file->b.nc && textreadc(t, q0)!='\n') ++ q0++; ++ if (q0 == (t->file->b.nc)-1) { ++ textshow(t, q0, q0, TRUE); ++ return; ++ } ++ q0++; ++ /* find old pos in ln */ ++ while(q1>1 && textreadc(t, q1)!='\n'){ ++ nnb++; ++ q1--; ++ } ++ /* go right until reachg pos or \n */ ++ while(q0file->b.nc && (nnb>0 && textreadc(t, q0)!='\n')){ ++ q0++; ++ nnb--; ++ } ++ if (q0>1 && q0file->b.nc) ++ textshow(t, q0, q0, TRUE); + return; +- case Kend: ++ case Kup: ++ if(t->what == Tag) ++ goto Tagup; + typecommit(t); +- if(t->iq1 > t->org+t->fr.nchars) { +- if(t->iq1 > t->file->b.nc) { +- // should not happen, but does. and it will crash textbacknl. +- t->iq1 = t->file->b.nc; +- } +- q0 = textbacknl(t, t->iq1, 1); +- textsetorigin(t, q0, TRUE); +- } else +- textshow(t, t->file->b.nc, t->file->b.nc, FALSE); ++ nnb = 0; ++ if(t->q0>0 && textreadc(t, t->q0-1)!='\n') ++ nnb = textbswidth(t, 0x15); ++ /* BOL - 1 if not first line of txt BOL*/ ++ if( t->q0-nnb > 1 && textreadc(t, t->q0-nnb-1)=='\n' ) nnb++; ++ textshow(t, t->q0-nnb, t->q0-nnb, TRUE); + return; +- case 0x01: /* ^A: beginning of line */ ++ ++/* ++ * Home and End now respectively take you to the ++ * beginning and to the end of the line respectively. ++ * Also keep the original ^A and ^E keybindings. ++ */ ++ ++ case 0x01: ++ case Khome: + typecommit(t); + /* go to where ^U would erase, if not already at BOL */ + nnb = 0; +@@ -803,13 +777,17 @@ texttype(Text *t, Rune r) + nnb = textbswidth(t, 0x15); + textshow(t, t->q0-nnb, t->q0-nnb, TRUE); + return; +- case 0x05: /* ^E: end of line */ ++ case 0x05: ++ case Kend: + typecommit(t); + q0 = t->q0; + while(q0file->b.nc && textreadc(t, q0)!='\n') + q0++; + textshow(t, q0, q0, TRUE); + return; ++ ++/* I'll keep the MAC-keybindings 'cuz im such a nice guy */ ++ + case Kcmd+'c': /* %C: copy */ + typecommit(t); + cut(t, t, nil, TRUE, FALSE, nil, 0); +@@ -821,20 +799,34 @@ texttype(Text *t, Rune r) + case Kcmd+'Z': /* %-shift-Z: redo */ + typecommit(t); + undo(t, nil, nil, FALSE, 0, nil, 0); +- return; +- case Kcmd+'s': /* %S: put */ ++ return; ++ ++/* ++ * Adding Windows and X11 -compatible Ctrl+C, Ctrl+Z and ++ * Ctrl+Y (for redoing). TODO: find out how to check out for ++ * shift press, for Ctrl+Shift+Z in this godforsaken switch() ++ */ ++ ++ case 0x03: /* Ctrl+C: copy */ + typecommit(t); +- put(&t->w->body, nil, nil, XXX, XXX, nil, 0); ++ cut(t, t, nil, TRUE, FALSE, nil, 0); ++ return; ++ case 0x1A: /* Ctrl+Z: undo */ ++ typecommit(t); ++ undo(t, nil, nil, TRUE, 0, nil, 0); ++ return; ++ case 0x19: /* Ctrl+Y: redo */ ++ typecommit(t); ++ undo(t, nil, nil, FALSE, 0, nil, 0); + return; + + Tagdown: + /* expand tag to show all text */ + if(!t->w->tagexpand){ +- t->w->tagexpand = TRUE; +- winresize(t->w, t->w->r, FALSE, TRUE); ++ t->w->tagexpand = TRUE; ++ winresize(t->w, t->w->r, FALSE, TRUE); + } + return; +- + Tagup: + /* shrink tag to single line */ + if(t->w->tagexpand){ +@@ -844,11 +836,16 @@ texttype(Text *t, Rune r) + } + return; + } ++ ++ ++ + if(t->what == Body){ + seq++; + filemark(t->file); + } +- /* cut/paste must be done after the seq++/filemark */ ++ ++ /* cut/paste must be done after the seq++/filemark */ ++ + switch(r){ + case Kcmd+'x': /* %X: cut */ + typecommit(t); +@@ -870,7 +867,31 @@ texttype(Text *t, Rune r) + textshow(t, t->q0, t->q1, 1); + t->iq1 = t->q1; + return; ++ ++ /* Same for Windows / X11 */ ++ ++ case 0x18: /* Ctrl+X: cut */ ++ typecommit(t); ++ if(t->what == Body){ ++ seq++; ++ filemark(t->file); ++ } ++ cut(t, t, nil, TRUE, TRUE, nil, 0); ++ textshow(t, t->q0, t->q0, 1); ++ t->iq1 = t->q0; ++ return; ++ case 0x16: /* Ctrl+V: paste */ ++ typecommit(t); ++ if(t->what == Body){ ++ seq++; ++ filemark(t->file); ++ } ++ paste(t, t, nil, TRUE, FALSE, nil, 0); ++ textshow(t, t->q0, t->q1, 1); ++ t->iq1 = t->q1; ++ return; + } ++ + if(t->q1 > t->q0){ + if(t->ncache != 0) + error("text.type"); +@@ -878,6 +899,7 @@ texttype(Text *t, Rune r) + t->eq0 = ~0; + } + textshow(t, t->q0, t->q0, 1); ++ + switch(r){ + case 0x06: /* ^F: complete */ + case Kins: +@@ -898,9 +920,17 @@ texttype(Text *t, Rune r) + typecommit(t); + t->iq1 = t->q0; + return; ++ ++/* ++ * quick hack for DELETE-key, just added it to see what happens and ++ * apparently it works like ^U and erases whole lines. i should learn c ++ */ ++ ++ + case 0x08: /* ^H: erase character */ + case 0x15: /* ^U: erase line */ +- case 0x17: /* ^W: erase word */ ++ case 0x7F: ++ case 0x17: /* ^W: erase word */ + if(t->q0 == 0) /* nothing to erase */ + return; + nnb = textbswidth(t, r); +@@ -941,20 +971,8 @@ texttype(Text *t, Rune r) + textfill(t->file->text[i]); + t->iq1 = t->q0; + return; +- case '\t': +- if(t->what == Body && t->w->indent & IndentSpaces){ +- /* find beginning of previous line using backspace code */ +- nnb = textbswidth(t, 0x15); /* ^U case */ +- if(nnb == 1 && textreadc(t, t->q0-1) == '\n') +- nnb = 0; +- nnb = t->tabstop - nnb % t->tabstop; +- rp = runemalloc(nnb); +- for(nr = 0; nr < nnb; nr++) +- rp[nr] = ' '; +- } +- break; /* fall through to normal code */ + case '\n': +- if(t->w->indent & IndentAuto){ ++ if(t->w->autoindent){ + /* find beginning of previous line using backspace code */ + nnb = textbswidth(t, 0x15); /* ^U case */ + rp = runemalloc(nnb + 1); +@@ -1258,7 +1276,7 @@ void + textsetselect(Text *t, uint q0, uint q1) + { + int p0, p1, ticked; +- ++ + /* t->fr.p0 and t->fr.p1 are always right; t->q0 and t->q1 may be off */ + t->q0 = q0; + t->q1 = q1; +@@ -1411,7 +1429,7 @@ textselect23(Text *t, uint *q0, uint *q1, Image *high, int mask) + { + uint p0, p1; + int buts; +- ++ + p0 = xselect(&t->fr, mousectl, high, &p1); + buts = mousectl->m.buttons; + if((buts & mask) == 0){ +@@ -1478,7 +1496,7 @@ textdoubleclick(Text *t, uint *q0, uint *q1) + + if(textclickhtmlmatch(t, q0, q1)) + return; +- ++ + for(i=0; left[i]!=nil; i++){ + q = *q0; + l = left[i]; +@@ -1510,7 +1528,7 @@ textdoubleclick(Text *t, uint *q0, uint *q1) + return; + } + } +- ++ + /* try filling out word to right */ + while(*q1file->b.nc && isalnum(textreadc(t, *q1))) + (*q1)++; +@@ -1584,7 +1602,7 @@ static int + ishtmlend(Text *t, uint q, uint *q0) + { + int c, c1, c2; +- ++ + if(q < 2) + return 0; + if(textreadc(t, --q) != '>') +@@ -1612,7 +1630,7 @@ textclickhtmlmatch(Text *t, uint *q0, uint *q1) + { + int depth, n; + uint q, nq; +- ++ + q = *q0; + // after opening tag? scan forward for closing tag + if(ishtmlend(t, q, nil) == 1) { +@@ -1649,7 +1667,7 @@ textclickhtmlmatch(Text *t, uint *q0, uint *q1) + q--; + } + } +- ++ + return 0; + } + +diff --git a/src/cmd/acme/util.c b/src/cmd/acme/util.c +index 64ad4919..d694634f 100644 +--- a/src/cmd/acme/util.c ++++ b/src/cmd/acme/util.c +@@ -107,7 +107,7 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl) + runemove(r, incl[i], n); + winaddincl(w, r, n); + } +- w->indent = globalindent; ++ w->autoindent = globalautoindent; + return w; + } + +@@ -132,7 +132,7 @@ errorwin(Mntdir *md, int owner) + } + + /* +- * Incoming window should be locked. ++ * Incoming window should be locked. + * It will be unlocked and returned window + * will be locked in its place. + */ +@@ -189,7 +189,7 @@ void + addwarningtext(Mntdir *md, Rune *r, int nr) + { + Warning *warn; +- ++ + for(warn = warnings; warn; warn=warn->next){ + if(warn->md == md){ + bufinsert(&warn->buf, warn->buf.nc, r, nr); +@@ -276,8 +276,6 @@ runeeq(Rune *s1, uint n1, Rune *s2, uint n2) + { + if(n1 != n2) + return FALSE; +- if(n1 == 0) +- return TRUE; + return memcmp(s1, s2, n1*sizeof(Rune)) == 0; + } + +diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c +index d3763239..19b52f5c 100644 +--- a/src/cmd/acme/wind.c ++++ b/src/cmd/acme/wind.c +@@ -80,10 +80,10 @@ wininit(Window *w, Window *clone, Rectangle r) + draw(screen, br, button, nil, button->r.min); + w->filemenu = TRUE; + w->maxlines = w->body.fr.maxlines; +- w->indent = globalindent; ++ w->autoindent = globalautoindent; + if(clone){ + w->dirty = clone->dirty; +- w->indent = clone->indent; ++ w->autoindent = clone->autoindent; + textsetselect(&w->body, clone->body.q0, clone->body.q1); + winsettag(w); + } +@@ -97,7 +97,7 @@ windrawbutton(Window *w) + { + Image *b; + Rectangle br; +- ++ + b = button; + if(!w->isdir && !w->isscratch && (w->body.file->mod || w->body.ncache)) + b = modbutton; +@@ -110,22 +110,25 @@ windrawbutton(Window *w) + int + delrunepos(Window *w) + { +- Rune *r; +- int i; +- +- r = parsetag(w, 0, &i); +- free(r); +- i += 2; +- if(i >= w->tag.file->b.nc) ++ int n; ++ Rune rune; ++ ++ for(n=0; ntag.file->b.nc; n++) { ++ bufread(&w->tag.file->b, n, &rune, 1); ++ if(rune == ' ') ++ break; ++ } ++ n += 2; ++ if(n >= w->tag.file->b.nc) + return -1; +- return i; ++ return n; + } + + void + movetodel(Window *w) + { + int n; +- ++ + n = delrunepos(w); + if(n < 0) + return; +@@ -150,7 +153,7 @@ wintaglines(Window *w, Rectangle r) + textresize(&w->tag, r, TRUE); + w->tag.fr.noredraw = 0; + w->tagsafe = FALSE; +- ++ + if(!w->tagexpand) { + /* use just as many lines as needed to show the Del */ + n = delrunepos(w); +@@ -159,7 +162,7 @@ wintaglines(Window *w, Rectangle r) + p = subpt(frptofchar(&w->tag.fr, n), w->tag.fr.r.min); + return 1 + p.y / w->tag.fr.font->height; + } +- ++ + /* can't use more than we have */ + if(w->tag.fr.nlines >= w->tag.fr.maxlines) + return w->tag.fr.maxlines; +@@ -221,7 +224,7 @@ winresize(Window *w, Rectangle r, int safe, int keepextra) + moveto(mousectl, p); + } + } +- ++ + /* If needed, resize & redraw body. */ + r1 = r; + r1.min.y = y; +@@ -290,7 +293,7 @@ winunlock(Window *w) + void + winmousebut(Window *w) + { +- moveto(mousectl, addpt(w->tag.scrollr.min, ++ moveto(mousectl, addpt(w->tag.scrollr.min, + divpt(Pt(Dx(w->tag.scrollr), font->height), 2))); + } + +@@ -416,7 +419,11 @@ wincleartag(Window *w) + + /* w must be committed */ + n = w->tag.file->b.nc; +- r = parsetag(w, 0, &i); ++ r = runemalloc(n); ++ bufread(&w->tag.file->b, 0, r, n); ++ for(i=0; itag, w->tag.q0, w->tag.q1); + } + +-Rune* +-parsetag(Window *w, int extra, int *len) +-{ +- static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 'r', 'f', 0 }; +- static Rune Lspacepipe[] = { ' ', '|', 0 }; +- static Rune Ltabpipe[] = { '\t', '|', 0 }; +- int i; +- Rune *r, *p, *pipe; +- +- r = runemalloc(w->tag.file->b.nc+extra+1); +- bufread(&w->tag.file->b, 0, r, w->tag.file->b.nc); +- r[w->tag.file->b.nc] = '\0'; +- +- /* +- * " |" or "\t|" ends left half of tag +- * If we find " Del Snarf" in the left half of the tag +- * (before the pipe), that ends the file name. +- */ +- pipe = runestrstr(r, Lspacepipe); +- if((p = runestrstr(r, Ltabpipe)) != nil && (pipe == nil || p < pipe)) +- pipe = p; +- if((p = runestrstr(r, Ldelsnarf)) != nil && (pipe == nil || p < pipe)) +- i = p - r; +- else { +- for(i=0; itag.file->b.nc; i++) +- if(r[i]==' ' || r[i]=='\t') +- break; +- } +- *len = i; +- return r; +-} +- + void + winsettag1(Window *w) + { +@@ -483,7 +458,12 @@ winsettag1(Window *w) + /* there are races that get us here with stuff in the tag cache, so we take extra care to sync it */ + if(w->tag.ncache!=0 || w->tag.file->mod) + wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag contents */ +- old = parsetag(w, 0, &i); ++ old = runemalloc(w->tag.file->b.nc+1); ++ bufread(&w->tag.file->b, 0, old, w->tag.file->b.nc); ++ old[w->tag.file->b.nc] = '\0'; ++ for(i=0; itag.file->b.nc; i++) ++ if(old[i]==' ' || old[i]=='\t') ++ break; + if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){ + textdelete(&w->tag, 0, i, TRUE); + textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE); +@@ -496,8 +476,7 @@ winsettag1(Window *w) + /* compute the text for the whole tag, replacing current only if it differs */ + new = runemalloc(w->body.file->nname+100); + i = 0; +- if(w->body.file->nname != 0) +- runemove(new, w->body.file->name, w->body.file->nname); ++ runemove(new+i, w->body.file->name, w->body.file->nname); + i += w->body.file->nname; + runemove(new+i, Ldelsnarf, 10); + i += 10; +@@ -604,7 +583,11 @@ wincommit(Window *w, Text *t) + textcommit(f->text[i], FALSE); /* no-op for t */ + if(t->what == Body) + return; +- r = parsetag(w, 0, &i); ++ r = runemalloc(w->tag.file->b.nc); ++ bufread(&w->tag.file->b, 0, r, w->tag.file->b.nc); ++ for(i=0; itag.file->b.nc; i++) ++ if(r[i]==' ' || r[i]=='\t') ++ break; + if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){ + seq++; + filemark(w->body.file); +@@ -689,7 +672,7 @@ winctlprint(Window *w, char *buf, int fonts) + sprint(buf, "%11d %11d %11d %11d %11d ", w->id, w->tag.file->b.nc, + w->body.file->b.nc, w->isdir, w->dirty); + if(fonts) +- return smprint("%s%11d %q %11d ", buf, Dx(w->body.fr.r), ++ return smprint("%s%11d %q %11d ", buf, Dx(w->body.fr.r), + w->body.reffont->f->name, w->body.fr.maxtab); + return buf; + } +diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c +index e7d9f4cb..5aa4a180 100644 +--- a/src/cmd/acme/xfid.c ++++ b/src/cmd/acme/xfid.c +@@ -701,24 +701,6 @@ out: + winsetname(w, r, nr); + m += (q+1) - pp; + }else +- if(strncmp(p, "font ", 5) == 0){ /* execute font command */ +- pp = p+5; +- m = 5; +- q = memchr(pp, '\n', e-pp); +- if(q==nil || q==pp){ +- err = Ebadctl; +- break; +- } +- *q = 0; +- nulls = FALSE; +- cvttorunes(pp, q-pp, r, &nb, &nr, &nulls); +- if(nulls){ +- err = "nulls in font string"; +- break; +- } +- fontx(&w->body, nil, nil, FALSE, XXX, r, nr); +- m += (q+1) - pp; +- }else + if(strncmp(p, "dump ", 5) == 0){ /* set dump string */ + pp = p+5; + m = 5; +@@ -808,12 +790,10 @@ out: + }else + if(strncmp(p, "nomenu", 6) == 0){ /* turn off automatic menu */ + w->filemenu = FALSE; +- settag = TRUE; + m = 6; + }else + if(strncmp(p, "menu", 4) == 0){ /* enable automatic menu */ + w->filemenu = TRUE; +- settag = TRUE; + m = 4; + }else + if(strncmp(p, "cleartag", 8) == 0){ /* wipe tag right of bar */