From 107e8163242a1dbe58b093d3fe53b3eead7281ea Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Mon, 1 Aug 2005 21:05:29 +0000
Subject: [PATCH] eliminate still more redundant screen updates

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2969 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog   |  4 +++-
 src/proto.h |  2 +-
 src/winio.c | 40 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c046bc8b..1238f1f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,7 +43,9 @@ CVS code -
 	  it, and (b) no longer call edit_redraw() afterward, as it's
 	  now unnecessary.  These changes eliminate redundant screen
 	  updates when the mark is on, since the mark display depends on
-	  current and current_x.  Changes to edit_scroll(),
+	  current and current_x.  Also change edit_redraw() to use
+	  edit_scroll() instead of edit_refresh() when one of its two
+	  reference lines is offscreen.  Changes to edit_scroll(),
 	  do_page_up(), do_page_down(), do_up(), and do_down(). (DLR)
 	- Consistently make the fg and bg colortype struct entries and
 	  any variables used to hold them shorts.  Changes to
diff --git a/src/proto.h b/src/proto.h
index ab83bbac..d3d5ee7c 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -666,7 +666,7 @@ void edit_add(const filestruct *fileptr, const char *converted, int
 void update_line(const filestruct *fileptr, size_t index);
 int need_horizontal_update(size_t old_pww);
 int need_vertical_update(size_t old_pww);
-void edit_scroll(scroll_dir direction, int nlines);
+void edit_scroll(scroll_dir direction, ssize_t nlines);
 void edit_redraw(const filestruct *old_current, size_t old_pww);
 void edit_refresh(void);
 void edit_update(update_type location);
diff --git a/src/winio.c b/src/winio.c
index cef527a6..92a05f7a 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3478,11 +3478,11 @@ int need_vertical_update(size_t old_pww)
  * and nlines is the number of lines to scroll.  We change edittop, and
  * assume that current and current_x are up to date.  We also assume
  * that scrollok(edit) is FALSE. */
-void edit_scroll(scroll_dir direction, int nlines)
+void edit_scroll(scroll_dir direction, ssize_t nlines)
 {
     bool do_redraw = need_vertical_update(0);
     const filestruct *foo;
-    int i;
+    ssize_t i;
 
     /* Don't bother scrolling less than one line. */
     if (nlines < 1)
@@ -3537,6 +3537,14 @@ void edit_scroll(scroll_dir direction, int nlines)
     if (nlines > editwinrows)
 	nlines = editwinrows;
 
+    /* If we need to redraw the entire edit window, don't bother
+     * scrolling every line offscreen.  Just call edit_refresh() and get
+     * out. */
+    if (nlines == editwinrows) {
+	edit_refresh();
+	return;
+    }
+
     /* If we scrolled up, we're on the line before the scrolled
      * region. */
     foo = openfile->edittop;
@@ -3574,14 +3582,36 @@ void edit_redraw(const filestruct *old_current, size_t old_pww)
 	need_vertical_update(old_pww);
     const filestruct *foo;
 
-    /* If either old_current or current is offscreen, refresh the screen
-     * and get out. */
+    /* If either old_current or current is offscreen, scroll the edit
+     * window until it's onscreen and get out. */
     if (old_current->lineno < openfile->edittop->lineno ||
 	old_current->lineno >= openfile->edittop->lineno +
 	editwinrows || openfile->current->lineno <
 	openfile->edittop->lineno || openfile->current->lineno >=
 	openfile->edittop->lineno + editwinrows) {
-	edit_refresh();
+	filestruct *old_edittop = openfile->edittop;
+	ssize_t nlines;
+
+	/* Put edittop in range of current, get the difference in lines
+	 * between the original edittop and the current edittop, and
+	 * then restore the original edittop. */
+	edit_update(
+#ifndef NANO_SMALL
+		ISSET(SMOOTH_SCROLL) ? NONE :
+#endif
+		CENTER);
+
+	nlines = openfile->edittop->lineno - old_edittop->lineno;
+
+	openfile->edittop = old_edittop;
+
+	/* Scroll the edit window until edittop is in range of
+	 * current. */
+	if (nlines < 0)
+	    edit_scroll(UP, -nlines);
+	else
+	    edit_scroll(DOWN, nlines);
+
 	return;
     }
 
-- 
GitLab