dca@toylnd.UUCP (David C. Albrecht) (10/31/87)
I use micro emacs v3.8 regularly on a uVAXEN, a AT&T 3b1, and an Amiga. One of the things I noticed was that while it is regularly quite speedy, that splitting a window onto a single buffer really makes it bog down. A little poking around and I realised why. Basically when the same buffer appears on more than one window it causes a total redisplay on any alterations even when they effect only one line and even if that line doesn't appear in the window. Ack. I tend to split windows on one buffer alot. Therefore using my 5 minute study of micro emacs I proceeded to make this hack. Seems to be pretty clean code, hate to muck it up, hate the slow insertion worse. I would appreciate if more guru'esq types would respond if said hack will cause any problems. It does, however, speed windows split onto a single file up to the point where if the line you are altering doesn't appear in the split window there is no visible degradation and even if it does it is still faster than the old method. Basically me3.8 uses a routine called lchange to set the flags in the window buffer when a buffer is altered. lchange can be found in line.c. previously it said: if (curbp->b_nwnd != 1) /* Ensure hard. */ flag = WFHARD; i.e. always cause redisplay on multiply referenced buffers. WFEDIT seems to be alterations occuring only on one line so I changed this to. if (curbp->b_nwnd != 1 && flag != WFEDIT) /* Ensure hard. */ flag = WFHARD; Ok. Now the routine 'update' refreshes the screen this can be found in display.c. In update, there is a line which tests the flag for updating one line and if it is set updates it. if ((wp->w_flag & ~WFMODE) == WFEDIT) updone(wp); /* update EDITed line */ Basically, updone searches the window for the line at wp->w_dotp so that it can find it in the virtual screen. Only the current window, however, has the alteration just made at w_dotp. Therefore I added the w_dotp parameter to updone instead of having it extract it from wp and supplied the w_dotp for the current window. Thusly: if ((wp->w_flag & ~WFMODE) == WFEDIT) updone(wp, curwp->w_dotp); /* update EDITed line */ Of course I altered updone to read: updone(wp, upd) WINDOW *wp; /* window to update current line in */ register LINE *upd; /* line to update */ And the search part which read: /* search down the line we want */ lp = wp->w_linep; sline = wp->w_toprow; while (lp != wp->w_dotp) { ++sline; lp = lforw(lp); } I altered to exit if the line doesn't appear on the screen and to use my new upd parameter. /* search down the line we want */ lp = wp->w_linep; sline = wp->w_toprow; i = wp->w_ntrows; while (i-- && lp != upd) { ++sline; lp = lforw(lp); } if (i < 0) return; /* line doesn't appear on screen */ I tried to get it to break and haven't suceeded yet. David Albrecht