Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/17/84; site godot.UUCP Path: utzoo!watmath!clyde!cbosgd!ihnp4!godot!massar From: massar@godot.UUCP (J.P. Massar) Newsgroups: net.emacs Subject: CCA Emacs Redisplay Bug Fix Message-ID: <1076@godot.UUCP> Date: Tue, 26-Feb-85 16:08:27 EST Article-I.D.: godot.1076 Posted: Tue Feb 26 16:08:27 1985 Date-Received: Thu, 28-Feb-85 20:14:01 EST Distribution: net Organization: Thinking Machines, Cambridge, MA Lines: 174 At times, especially when the load average is high, and especially when you have the Time Display option set, Emacs would screw up redisplaying the screen after processing a lot of typed characters. For instance, if you typed 'abcdefghij' quickly Emacs might print 'abc' then pause and process the rest of the characters you typed without displaying them, then display the rest of the line which might look like abcefghj i.e., some characters might be 'missing'. ('missing' because by typing C-L the proper line abcdefghij will be displayed). The problem is basically that during the times Emacs processes input without displaying it, it can get confused as to where the cursor really is. Here is an essentially simple fix which solves the problem with respect to Time Display. Included in this is a fix which makes Emacs only check for mail once a minute (as opposed to what it does now, which is to check every time you type a character! (this checking does a 'stat' system call, which presumably generates a signficant amount of I/O and processing)). The fix is entirely within e_main.c. I cannot provide diffs because of other changes I have made. Instead, I provide source for the two routines that need changing: edit and timed. My first impressions are that with these fixes Emacs handles much better under heavy loads. These fixes do not solve the problem entirely. There are undoubtably other places in the code where Emacs does similar things and likewise gets confused about where the cursor is. One of these may be when it does Auto Save's. Basically any time Emacs displays something in the mode line or in the Echo area there is the possibly that this bug could be present, although it is not necessarily present. Now that the bug is understood, if anyone can produce it in circumstances other than time redisplay it can probably be tracked down and fixed. I don't promise to fix these cases, but I'd be interested in hearing about the cases where it still happens. *************************************************************************** /***** Replace the code for edit in e_main with the following *****/ *************************************************************************** #define DELTA_DT 5 /* seconds between time redisplays */ #define DELTA_MCHECK 60 /* seconds between mail checks */ static long clock,mailctime,dtctime; /* EMACS main editing loop */ edit(earg) { register i; char retval; for (;;) { if (mlhexf && !infile && (i = binsrch("Main Loop Hook", (char *)comtab, NCOMS, sizeof(struct key))) >= 0 && i < NCOMS) { xcnum = i; (void)(*comtab[i].func)(1, -1, 0, 0, 0); } disp = echocom = flushed = longline = numarg = piperr = quitf = signonly = autargf = 0; if (Savemd && ++nschar >= Saveint) asave(); updis(); if (bgspellf && !access(sptemp, 0)) { echo2("Background Spell has finished."); rdisputc(Ctrl('G')); fflush(stdout); sleep(1); goback(); bgspellf = 0; } time(&clock); #if vms ckmsgs(); /* Check for broadcast messages */ #endif #if !vms /* check for mail every so often if not processing typeahead */ if (Mailnote && clock > mailctime + DELTA_MCHECK && empty(0)) { mailctime = clock; ckmail(1, 0); } #endif /* redisplay the time if we're not processing typeahead */ /* and some number of seconds have passed */ if (Timemd && clock > dtctime + DELTA_DT && empty(0)) { dtctime = clock; dtime(); } #if BSD42 if (streqn(TERM, "sun", 3) && empty(0) && !findloc(curline, curcol)) cc = blincur(); else #endif cc = getchar(); if (prtermf) { prtermf = 0; continue; /* Dummy character */ } if (krappf) krappf--; if (vcolflg) vcolflg--; if (Autargm && (isdigit(cc) || cc == '-')) { autargf = 1; retval = autoarg(); } else { if (Abbrevmd && (index(Abbexpch, cc) || *Addabbex && index(Addabbex, cc))) expabb(); retval = keyex(1); } Sedit++; if (!earg || exitf || quitf && infile && !recovery) return(retval); } } *************************************************************************** /***** Replace the code for edit in e_main with the following *****/ *************************************************************************** /* Display the time in the lower right hand corner of the screen */ dtime() { register char *tp; register len; char dtimebuf[SBUFSIZ]; int x; int y; tp = ctime(&clock); tp[16] = 0; x = mapline; y = mapcol; if (*echo2buf && *echo2buf != ' ') { sprintf(dtimebuf, " %s", tp); len = min(strlen(echo2buf), 56); (void) strcpy(echo2buf + len, dtimebuf + len); echo2(echo2buf); } else echo2(" %s", tp); newpos(x, y); } -- -- JP Massar, Thinking Machines Corporation, Cambridge, MA -- ihnp4!godot!massar -- massar@cca-unix