[comp.emacs] Mod to micro emacs 3.8i

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