[comp.emacs] Scrolling in GNU emacs

djs@cbnews.ATT.COM (Douglas J. Scofea) (08/10/89)

I am using GNU emacs 18.53 on an Amdahl running UTS (mostly System 5 
release 2).  Under some conditions, emacs will redraw the entire screen 
just to scroll one line, which is very slow.  The terminal is an AT&T 
5620 but it also occurs on a Teletype 4425 (pretty much a standard ANSI 
terminal). 

I've read $EMACS/etc/TERMS and tryed making some changes to the terminfo 
description, but it just made things worse.  The terminfo description
has no padding in it at all.  The problem occurs when the screen is
mostly full of a narrow column of text, like a large case statement in
C or a terminfo description.  Under these conditions, emacs will redraw
the entire display to scroll one line.  If it matters, I have scroll-step
set to 1.  When the same file is scrolled in vi, no problems occur.

I figure it has to be something in the terminfo description making emacs 
think that scrolling the terminal would be slow compared to redrawing the 
screen.  However, since there is no padding, and a scroll is at most
a few escape sequences, I can't understand what would cause this.

If anyone has some suggestions about things to try, please post them
or mail to the address below.  Thanks.

--
Doug Scofea  -  djs@cbnews.ATT.COM      Phone: +1 614 860 2065
UUCP:   ...!att!cblpn!djs
-- 
Doug Scofea  -  djs@cblpn.ATT.COM      Phone: +1 614 860 2065
UUCP:   ...!att!cblpn!djs

tom@ssd.harris.com (Tom Horsley) (08/10/89)

>I am using GNU emacs 18.53 on an Amdahl running UTS (mostly System 5 
>release 2).  Under some conditions, emacs will redraw the entire screen 
>just to scroll one line, which is very slow.

This annoys me all the time as well. As near as I can tell, it is done
deliberately in the display code and is impossible to fix without code
changes. You would think that if a terminal has scrolling regions, it would
*always* be faster to scroll, but it does some sort of cryptic computations
that wind up deducing it is faster to redraw the whole screen than to
scroll:

In the gnuemacs 18.52 source, file xdisp.c, the following comment appears:
	  /* If reprinting everything is nearly as fast as scrolling,
	     don't bother scrolling.  Can happen if lines are short.  */

If anyone has ever fixed this foible, please post your mods!
--
=====================================================================
    usenet: tahorsley@ssd.harris.com  USMail: Tom Horsley
compuserve: 76505,364                         511 Kingbird Circle
     genie: T.HORSLEY                         Delray Beach, FL  33444
======================== Aging: Just say no! ========================

montnaro@sprite.crd.ge.com (Skip Montanaro) (08/11/89)

In article <TOM.89Aug10071424@hcx2.ssd.harris.com> tom@ssd.harris.com (Tom Horsley) writes:

   >I am using GNU emacs 18.53 on an Amdahl running UTS (mostly System 5 
   >release 2).  Under some conditions, emacs will redraw the entire screen 
   >just to scroll one line, which is very slow.

   This annoys me all the time as well. As near as I can tell, it is done
   deliberately in the display code and is impossible to fix without code
   changes.

Double check what Emacs thinks your baud rate is with 'stty'. For example,
when I connect from home, I go through a terminal server on our Ethernet. It
telnets to my Sun, so when I log in, it sets my baud rate to 38400. 'stty
2400' cures this problem.

Another problem is presumed delays for different operations. If /etc/termcap
(or the terminfo equivalent) penalizes scrolling operations heavily, Emacs
will often avoid those operations. You must also make sure your terminal is
completely described by termcap/terminfo. If your terminal can scroll, but
this isn't described in termcap/terminfo, then Emacs won't use that
capability. For a brief treatise on terminal issues, check out etc/TERMS in
the GNU Emacs directory. For a more thorough treatment of termcap, check out
the termcap manual in Info.
--
Skip Montanaro (montanaro@sprite.crd.ge.com)

kjones@talos.uucp (Kyle Jones) (08/14/89)

Tom Horsley writes:
 > You would think that if a terminal has scrolling regions, it would
 > *always* be faster to scroll, but it does some sort of cryptic computations
 > that wind up deducing it is faster to redraw the whole screen than to
 > scroll:

Ho ho, just recently we had some users of X windows moaning that the
opposite is true.

It really and truly depends on what exactly is on the screen and how
much padding for the terminal's scrolling commands, be they scrolling
regions, scrolling forward/backward, or insert/delete line or all of
these.  In the case of windowing systems that don't provide a termcap (or
equivalent) information, then whether scrolling is fast or not depends
on the hardware driving the bitmapped display.

So if Emacs is making the wrong decision between scrolling and redrawing
then more than likely it's been given incorrect (or no) information to
work with.

rlk@think.com (Robert Krawitz) (08/17/89)

In article <1989Aug14.153236.13162@talos.uucp>, kjones@talos (Kyle Jones) writes:
]Tom Horsley writes:
] > You would think that if a terminal has scrolling regions, it would
] > *always* be faster to scroll, but it does some sort of cryptic computations
] > that wind up deducing it is faster to redraw the whole screen than to
] > scroll:
]So if Emacs is making the wrong decision between scrolling and redrawing
]then more than likely it's been given incorrect (or no) information to
]work with.

Gnu Emacs does make the wrong decisions when it comes to scrolling.  The
problem is that the emacs terminal driver was designed to work with
fixed-rate terminals with scrolling implemented in microcode or hardware
that is much faster than repainting the screen.  The X interface, at
least in versions 17 and 18, has stubs which are called by the terminal
driver; i. e. X simply replaces some of the low-level terminal driver
modules (this is even how the mouse is implemented).

I did some experiments several years ago with setting various
parameters, many of which are not user accessible (I wrote setter
functions for them).  My conclusion is that the right behavior is very
hard to determine.  Setting the baud rate to something much higher, like
1000000 rather than 9600, definitely helps substantially.  There are
other internal parameters (whose names I have long since forgotten) that
seem to penalize scrolling compared to repainting.  The problem is that
different displays have different characteristics, and the differences
are great enough to have substantial impact on a big emacs window (such
as 89 lines of 160 columns split horizontally into two windows).  It
also knows nothing about bitblt-type operations, which could save a lot
of time in these situations.  I hope RMS is investigating it for Version
19; it would be unfortunate if this wasn't improved.  On a color Sun,
the current scrolling behavior is dreadfully slow.
-- 
ames >>>>>>>>>  |	Robert Krawitz <rlk@think.com>	245 First St.
bloom-beacon >  |think!rlk				Cambridge, MA  02142
harvard >>>>>>  .	Thinking Machines Corp.		(617)876-1111

djs@cbnews.ATT.COM (Douglas J. Scofea) (09/08/89)

In article <1989Aug14.153236.13162@talos.uucp> kjones%talos.uucp@uunet.uu.net writes:

>Tom Horsley writes:
> > You would think that if a terminal has scrolling regions, it would
> > *always* be faster to scroll, but it does some sort of cryptic computations
> > that wind up deducing it is faster to redraw the whole screen than to
> > scroll:
>
>
>It really and truly depends on what exactly is on the screen and how
>much padding for the terminal's scrolling commands, be they scrolling
>regions, scrolling forward/backward, or insert/delete line or all of
>these.

Yes, but as I said in the original article, my terminal requires no
padding.  Thus, it didn't seem to make sense to redraw the screen
when a few escape sequences would suffice.  In my case, emacs would
redraw 64 lines to save a few escape sequences, hardly optimal redisplay.  

Thanks to those who posted the suggestions for the terminfo descriptions.  
However, none of them helped.  I think I've found the problem.  Tom
Horsley gave me a good hint when he pointed out that there was a comment
in xdisp.c that short lines were ignored when calculating the cost
of screen updates.  I tried some changes and finally tracked it
down to a routine called scrolling_max_lines_saved in scroll.c that
tries to calculate how many lines are the same between the old
display and the new display.  Unfortunately, it ignores lines of
less than 20 characters.  Thus, if all (most?) of the lines are
less than 20 characters, it feels that very little of the display
lines are the same and redraws the entire display.  I changed the
code to eliminate that test for greater than 20 character line length.
It may cause some new bugs, I haven't found any, but I can't say
I have a complete understanding of the display code.  If anyone
knows a better way to fix this, please let me know.  In any case
a context diff is given below of the change I made.  It was made
from GNU emacs 18.53.  Good luck.

*** scroll.c.orig	Tue Aug 15 13:12:51 1989
--- scroll.c	Tue Aug 15 14:14:41 1989
***************
*** 316,327
    /* Put new lines' hash codes in hash table.  */
    for (i = start; i < end; i++)
      {
!       if (cost[i] > 20)
! 	{
! 	  h = newhash[i] & 0777;
! 	  lines[h].hash = newhash[i];
! 	  lines[h].count++;
! 	}
      }
  
    /* Look up old line hash codes in the hash table.

--- 316,324 -----
    /* Put new lines' hash codes in hash table.  */
    for (i = start; i < end; i++)
      {
!       h = newhash[i] & 0777;
!       lines[h].hash = newhash[i];
!       lines[h].count++;
      }
  
    /* Look up old line hash codes in the hash table.
-- 
Doug Scofea  -  douglas.j.scofea@att.com      Phone: +1 614 860 2065
UUCP:   ...!att!cblpn!djs