From 50c7f2de2f2ef6fe1a561874cef81f6cc8b1589b Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Fri, 27 Aug 2004 17:02:05 +0000
Subject: [PATCH] have edit_refresh() call edit_update() with NONE when smooth
 scrolling is on so that smooth scrolling applies everywhere instead of just
 to the movement functions, fix a potential infinite loop when edit_update()
 is called with NONE and current_y is greater than (editwinrows - 1), and have
 do_para_begin() and do_para_end() maintain current_y as do_justify() does
 (and as they did before)

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1917 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog   | 13 +++++++++++++
 src/nano.c  |  5 ++++-
 src/winio.c | 43 ++++++++++++++++++++++++++++++++++++-------
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index da283fe1..c7d0a25c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,10 @@ CVS code -
 - global.c:
   shortcut_init()
 	- Remove redundant NANO_SMALL #ifdef. (DLR)
+- nano.c:
+  do_para_begin(), do_para_end()
+	- Maintain current_y as do_justify() does, for consistency with
+	  it. (DLR)
 - rcfile.c:
   parse_rcfile()
 	- Add missing brackets around an if statement block so that
@@ -29,9 +33,18 @@ CVS code -
 	- If there are more than MAIN_VISIBLE shortcuts available, only
 	  register clicks on the first MAIN_VISIBLE shortcuts, since
 	  bottombars() only shows that many shortcuts. (DLR)
+  edit_refresh()
+	- Call edit_update() with NONE instead of CENTER when smooth
+	  scrolling is on, for consistency with the movement routines.
+	  (DLR)
   edit_update()
 	- Simplify so as not to require the fileptr parameter anymore,
 	  since it's set to current in all calls. (DLR)
+	- Add comments better explaining what the update actually does,
+	  avoid an infinite loop when location is NONE and current_y is
+	  greater than (editwinrows - 1), and make sure that the bottom
+	  line of the file is at the bottom line of the screen if it's
+	  onscreen and location is NONE. (DLR)
   do_yesno()
 	- Don't bother assigning the value of get_mouseinput() to
 	  anything.  Since allow_shortcuts is FALSE, its return value
diff --git a/src/nano.c b/src/nano.c
index 06c67a82..7b09708d 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2024,6 +2024,7 @@ void do_para_begin(void)
     if (current->prev != NULL) {
 	do {
 	    current = current->prev;
+	    current_y--;
 	} while (!begpar(current));
     }
 
@@ -2052,8 +2053,10 @@ void do_para_end(void)
 	current = current->next;
 
     while (current->next != NULL && inpar(current->next->data) &&
-	    !begpar(current->next))
+	    !begpar(current->next)) {
 	current = current->next;
+	current_y++;
+    }
 
     if (current->next != NULL)
 	current = current->next;
diff --git a/src/winio.c b/src/winio.c
index a4a3a0b1..3411c17c 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -2893,11 +2893,14 @@ void edit_refresh(void)
 
     if (current->lineno < edittop->lineno ||
 	    current->lineno >= edittop->lineno + editwinrows)
-	/* Note that edit_update() changes edittop so that
-	 * current->lineno = edittop->lineno + editwinrows / 2.  Thus
-	 * when it then calls edit_refresh(), there is no danger of
-	 * getting an infinite loop. */
-	edit_update(CENTER);
+	/* Note that edit_update() changes edittop so that it's in range
+	 * of current.  Thus, when it then calls edit_refresh(), there
+	 * is no danger of getting an infinite loop. */
+	edit_update(
+#ifndef NANO_SMALL
+		ISSET(SMOOTHSCROLL) ? NONE :
+#endif
+		CENTER);
     else {
 	int nlines = 0;
 	const filestruct *foo = edittop;
@@ -2922,7 +2925,8 @@ void edit_refresh(void)
     }
 }
 
-/* A nice generic routine to update the edit buffer. */
+/* A nice generic routine to update the edit buffer.  We keep current in
+ * the same place and move edittop to put it in range of current. */
 void edit_update(topmidnone location)
 {
     filestruct *foo = current;
@@ -2932,11 +2936,36 @@ void edit_update(topmidnone location)
 	return;
 
     if (location != TOP) {
-	int goal = (location == NONE) ? current_y : editwinrows / 2;
+	/* If location is CENTER, we move edittop up (editwinrows / 2)
+	 * lines.  This puts current at the center of the screen.  If
+	 * location is NONE, we move edittop up current_y lines if
+	 * current_y is in range of the screen, 0 lines if current_y is
+	 * less than 0, or (editwinrows - 1) lines if current_y is
+	 * greater than (editwinrows - 1).  This puts current at the
+	 * same place on the screen as before, or at the top or bottom
+	 * of the screen if edittop is beyond either. */
+	int goal;
+
+	if (location == CENTER)
+	    goal = editwinrows / 2;
+	else {
+	    goal = current_y;
+
+	    /* Limit goal to (editwinrows - 1) lines maximum. */
+	    if (goal > editwinrows - 1)
+		goal = editwinrows - 1;
+
+	    /* If the last line of the file is onscreen but isn't at the
+	     * bottom of the screen, set goal so that it will be after
+	     * we update. */
+	    if (foo->lineno + editwinrows >= filebot->lineno)
+		goal = (editwinrows - 1) - (filebot->lineno - foo->lineno);
+	}
 
 	for (; goal > 0 && foo->prev != NULL; goal--)
 	    foo = foo->prev;
     }
+
     edittop = foo;
     edit_refresh();
 }
-- 
GitLab