diff --git a/ChangeLog b/ChangeLog
index db630782c8c2e8a82b8514bc3821f6501d9cc158..0b0125ed5f60edbedeedd146179bcdecb38e5ada 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,8 @@ CVS code -
 	  regardless of the original format.
 	- Mac file writing supported too.  Flag -M, --mac.  Toggle 
 	  Meta-O (MacOS? OS-X? =-)
+	- New smooth scroll code by Ken Tyler.  New flag -S, --smooth,
+	  changes to page_up() and page_down().
 - nano.c:
   main()
 	- Added vars oldcurrent and oldcurrent_x to check whether cursor
diff --git a/config.h.in b/config.h.in
index 7fcb8da22dbb99fcf7454829ffd99851f4240d61..02ba1537cee5270db11b3f348f51d9db07b6e346 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,4 +1,4 @@
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
 
 /* Define if using alloca.c.  */
 #undef C_ALLOCA
diff --git a/global.c b/global.c
index b01ef76a88fc185d04724e67f909d74310ed40a3..1623ea99468f133ebcad5a581702e9e686de345a 100644
--- a/global.c
+++ b/global.c
@@ -161,6 +161,8 @@ void toggle_init(void)
     char *toggle_regexp_msg;
 #endif
 
+    char *toggle_smooth_msg;
+
     toggle_const_msg = _("Constant cursor position");
     toggle_autoindent_msg = _("Auto indent");
     toggle_suspend_msg = _("Suspend");
@@ -172,6 +174,8 @@ void toggle_init(void)
     toggle_case_msg = _("Case Sensitive Search");
     toggle_dos_msg = _("Writing file in DOS format");
     toggle_mac_msg = _("Writing file in Mac format");
+    toggle_smooth_msg = _("Smooth scrolling");
+
 #ifdef HAVE_REGEX_H
     toggle_regexp_msg = _("Regular expressions");
 #endif
@@ -207,13 +211,15 @@ void toggle_init(void)
 		    DOS_FILE, 0);
     toggle_init_one(&toggles[11], TOGGLE_MAC_KEY, toggle_mac_msg,
 		    MAC_FILE, 0);
+    toggle_init_one(&toggles[12], TOGGLE_SMOOTH_KEY, toggle_smooth_msg,
+		    SMOOTHSCROLL, 0);
 
 #ifdef ENABLE_MULTIBUFFER
-    toggle_init_one(&toggles[12], TOGGLE_LOAD_KEY, toggle_load_msg,
+    toggle_init_one(&toggles[13], TOGGLE_LOAD_KEY, toggle_load_msg,
 		    MULTIBUFFER, 0);
-    toggle_init_one(&toggles[13], NANO_OPENPREV_KEY, nano_openprev_msg,
+    toggle_init_one(&toggles[14], NANO_OPENPREV_KEY, nano_openprev_msg,
 		    0, '<');
-    toggle_init_one(&toggles[14], NANO_OPENNEXT_KEY, nano_opennext_msg,
+    toggle_init_one(&toggles[15], NANO_OPENNEXT_KEY, nano_opennext_msg,
 		    0, '>');
 #endif
 
@@ -331,11 +337,11 @@ void shortcut_init(int unjustify)
 
     sc_init_one(&main_list[6], NANO_PREVPAGE_KEY, _("Prev Page"),
 		nano_prevpage_msg,
-		0, NANO_PREVPAGE_FKEY, KEY_PPAGE, VIEW, page_up);
+		0, NANO_PREVPAGE_FKEY, KEY_PPAGE, VIEW, do_page_up);
 
     sc_init_one(&main_list[7], NANO_NEXTPAGE_KEY, _("Next Page"),
 		nano_nextpage_msg,
-		0, NANO_NEXTPAGE_FKEY, KEY_NPAGE, VIEW, page_down);
+		0, NANO_NEXTPAGE_FKEY, KEY_NPAGE, VIEW, do_page_down);
 
     sc_init_one(&main_list[8], NANO_CUT_KEY, _("Cut Text"),
 		nano_cut_msg, 0, NANO_CUT_FKEY, 0, NOVIEW, do_cut_text);
@@ -492,11 +498,11 @@ void shortcut_init(int unjustify)
 
     sc_init_one(&help_list[0], NANO_PREVPAGE_KEY, _("Prev Page"),
 		nano_prevpage_msg,
-		0, NANO_PREVPAGE_FKEY, KEY_PPAGE, VIEW, page_up);
+		0, NANO_PREVPAGE_FKEY, KEY_PPAGE, VIEW, do_page_up);
 
     sc_init_one(&help_list[1], NANO_NEXTPAGE_KEY, _("Next Page"),
 		nano_nextpage_msg,
-		0, NANO_NEXTPAGE_FKEY, KEY_NPAGE, VIEW, page_down);
+		0, NANO_NEXTPAGE_FKEY, KEY_NPAGE, VIEW, do_page_down);
 
     sc_init_one(&help_list[2], NANO_EXIT_KEY, _("Exit"),
 		nano_exit_msg, 0, NANO_EXIT_FKEY, 0, VIEW, do_exit);
diff --git a/move.c b/move.c
index a5ba5f0e235ad284eeb136cfe968e0b60e3538e8..8f2802b9e0aebf4a08fb68b7eaed360476b6f210 100644
--- a/move.c
+++ b/move.c
@@ -34,20 +34,26 @@
 #define _(string) (string)
 #endif
 
-void page_down_center(void)
+void page_down(void)
 {
     if (editbot != filebot) {
-	edit_update(editbot->next, CENTER);
-	center_cursor();
+	if (!ISSET(SMOOTHSCROLL)) {
+	    edit_update(editbot->next, CENTER);
+	    center_cursor();
+	} else {
+	    edit_update(editbot, NONE);
+	}
     } else {
-	while (current != filebot)
-	    current = current->next;
-	edit_update(current, CENTER);
+	if (!ISSET(SMOOTHSCROLL)) {
+	    while (current != filebot)
+		current = current->next;
+	    edit_update(current, CENTER);
+	}
     }
     update_cursor();
 }
 
-int page_down(void)
+int do_page_down(void)
 {
     wrap_reset();
     current_x = 0;
@@ -124,7 +130,7 @@ int do_down(void)
     if (current_y < editwinrows - 1 && current != editbot)
 	current_y++;
     else
-	page_down_center();
+	page_down();
 
     update_cursor();
     update_line(current->prev, 0);
@@ -134,11 +140,15 @@ int do_down(void)
     return 1;
 }
 
-void page_up_center(void)
+void page_up(void)
 {
     if (edittop != fileage) {
-	edit_update(edittop, CENTER);
-	center_cursor();
+	if (!ISSET(SMOOTHSCROLL)) {
+	    edit_update(edittop, CENTER);
+	    center_cursor();
+	} else {
+	    edit_update(edittop->prev, NONE);
+	}
     } else
 	current_y = 0;
 
@@ -146,7 +156,7 @@ void page_up_center(void)
 
 }
 
-int page_up(void)
+int do_page_up(void)
 {
    int i;
 
@@ -184,7 +194,7 @@ int do_up(void)
     if (current_y > 0)
 	current_y--;
     else
-	page_up_center();
+	page_up();
 
     update_cursor();
     update_line(current->next, 0);
diff --git a/nano.c b/nano.c
index cb8a8aa229a605d2152a823e05ef90fa324a5bc4..b03b900f54382156666c30af89faa2a8d598c2bc 100644
--- a/nano.c
+++ b/nano.c
@@ -420,6 +420,10 @@ void usage(void)
 #ifdef HAVE_REGEX_H
     printf(_
 	   (" -R		--regexp		Use regular expressions for search\n"));
+#endif
+#ifndef NANO_SMALL
+    printf(_
+	   (" -S		--smooth		Smooth scrolling\n"));
 #endif
     printf(_
 	   (" -T [num]	--tabsize=[num]		Set width of a tab to num\n"));
@@ -487,6 +491,9 @@ void usage(void)
 #endif
     printf(_(" -T [num]	Set width of a tab to num\n"));
     printf(_(" -R		Use regular expressions for search\n"));
+#ifndef NANO_SMALL
+    printf(_(" -S		Smooth scrolling\n"));
+#endif
     printf(_(" -V 		Print version information and exit\n"));
     printf(_(" -c 		Constantly show cursor position\n"));
     printf(_(" -h 		Show this message\n"));
@@ -1216,7 +1223,7 @@ int do_backspace(void)
 		current = previous->next;
 	    else
 		current = previous;
-	    page_up_center();
+	    page_up();
 	} else {
 	    if (previous->next)
 		current = previous->next;
@@ -2446,7 +2453,9 @@ int main(int argc, char *argv[])
 #ifdef ENABLE_MULTIBUFFER
 	{"multibuffer", 0, 0, 'F'},
 #endif
-
+#ifndef NANO_SMALL
+	{"smooth", 0, 0, 'S'},
+#endif
 	{0, 0, 0, 0}
     };
 #endif
@@ -2467,11 +2476,11 @@ int main(int argc, char *argv[])
 #endif /* ENABLE_NANORC */
 
 #ifdef HAVE_GETOPT_LONG
-    while ((optchr = getopt_long(argc, argv, "h?DFMRT:Vabcefgijklmo:pr:s:tvwxz",
+    while ((optchr = getopt_long(argc, argv, "h?DFMRST:Vabcefgijklmo:pr:s:tvwxz",
 				 long_options, &option_index)) != EOF) {
 #else
     while ((optchr =
-	    getopt(argc, argv, "h?DFMRT:Vabcefgijklmo:pr:s:tvwxz")) != EOF) {
+	    getopt(argc, argv, "h?DFMRST:Vabcefgijklmo:pr:s:tvwxz")) != EOF) {
 #endif
 
 	switch (optchr) {
@@ -2502,6 +2511,11 @@ int main(int argc, char *argv[])
 	case 'R':
 	    SET(USE_REGEXP);
 	    break;
+#endif
+#ifndef NANO_SMALL
+	case 'S':
+	    SET(SMOOTHSCROLL);
+	    break;
 #endif
 	case 'V':
 	    version();
diff --git a/nano.h b/nano.h
index 7bac4000d749c9c0ec1d04a728d17b1df04f74e4..fa37f79adc6a1b2e27b7dbabbcd042401d52b8be 100644
--- a/nano.h
+++ b/nano.h
@@ -142,6 +142,7 @@ typedef struct rcoption {
 #define CLEAR_BACKUPSTRING	(1<<20)
 #define DOS_FILE		(1<<21)
 #define MAC_FILE		(1<<22)
+#define SMOOTHSCROLL		(1<<23)
 
 /* Control key sequences, changing these would be very very bad */
 
@@ -277,6 +278,7 @@ know what you're doing */
 #define TOGGLE_LOAD_KEY		NANO_ALT_F
 #define TOGGLE_DOS_KEY		NANO_ALT_D
 #define TOGGLE_MAC_KEY		NANO_ALT_O
+#define TOGGLE_SMOOTH_KEY	NANO_ALT_S
 
 /* Toggle stuff, these static lengths need to go away RSN */
 
@@ -310,7 +312,7 @@ know what you're doing */
 
 #define WHEREIS_LIST_LEN (8 - NO_REGEX - NO_TOGGLES)
 #define REPLACE_LIST_LEN (8 - NO_REGEX - NO_TOGGLES)
-#define TOGGLE_LEN (13 - NO_REGEX + MULTI_TOGGLES)
+#define TOGGLE_LEN (14 - NO_REGEX + MULTI_TOGGLES)
 #define WRITEFILE_LIST_LEN (3 - NO_BROWSER)
 #define INSERTFILE_LIST_LEN (2 - NO_BROWSER)
 #define BROWSER_LIST_LEN 4
diff --git a/nanorc.sample b/nanorc.sample
index 3ca2b895ea692b5cde655aef2ecc4446a1889348..683fe83bab1965e110d7d5b6f1121642424c77c8 100644
--- a/nanorc.sample
+++ b/nanorc.sample
@@ -44,6 +44,9 @@
 # Allow nano to be suspended with ^Z
 # set suspend
 
+# Use smooth scrolling as the default
+# set smooth
+
 # Allow multiple file buffers (using ^R inserts into separate buffer)
 # You must have configured with --enable-multibuffer or --enable-extra for
 # this to work
diff --git a/proto.h b/proto.h
index f112d0f13b617ec9aa42331a7c767d2871bc2dd9..a025c3d223eb96feeb5151c2d421f6a09f774d79 100644
--- a/proto.h
+++ b/proto.h
@@ -164,7 +164,7 @@ void new_file(void);
 void new_magicline(void);
 void splice_node(filestruct *begin, filestruct *newnode, filestruct *end);
 void null_at(char *data, int index);
-void page_up_center(void);
+void page_up(void);
 void blank_edit(void);
 void search_init_globals(void);
 void replace_abort(void);
@@ -194,7 +194,7 @@ int do_insertfile_void(void), do_search(void);
 int load_open_file(void), close_open_file(void);
 #endif
 
-int page_up(void), page_down(void);
+int do_page_up(void), do_page_down(void);
 int do_cursorpos(void), do_spell(void);
 int do_up(void), do_down (void), do_right(void), do_left (void);
 int do_home(void), do_end(void), total_refresh(void), do_mark(void);
diff --git a/rcfile.c b/rcfile.c
index 85eedc7d5158b4d9b7ff5edc687be44fd7355656..8c965987477d244ea21842e1e56d3b15be4f17c7 100644
--- a/rcfile.c
+++ b/rcfile.c
@@ -62,7 +62,8 @@ rcoption rcopts[NUM_RCOPTS] =
 {"nowrap", NO_WRAP}, 
 {"nohelp", NO_HELP}, 
 {"suspend", SUSPEND},
-{"multibuffer", MULTIBUFFER}};
+{"multibuffer", MULTIBUFFER},
+{"smooth", SMOOTHSCROLL}};
 
 /* We have an error in some part of the rcfile; put it on stderr and
   make the user hit return to continue starting up nano */