diff --git a/ChangeLog b/ChangeLog
index 2858533df2236d7f7b347e10de6ffe143b6c9521..6e10e3c42f3e69af14f5c431bbf5d563eeaeb5dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -71,13 +71,12 @@ CVS code -
 	  mbrevstrcasestr(), etc.; removal of is_alnum_char() and
 	  is_alnum_wchar(). (DLR)
 	- Implement word count via Meta-D at the main window.  Note that
-	  this is disabled when NANO_SMALL is defined.  New functions
-	  do_word_count() and do_next_word_void(); changes to
-	  shortcut_init() and do_next_word(). (DLR)
-	- Detect words more accurately by taking punctuation into
-	  account, and convert all word-detecting functions to use the
-	  same wrapper function for ease of maintenance.  New functions
-	  is_punct_mbchar() and is_word_mbchar(); changes to
+	  this is disabled when NANO_SMALL is defined.  Also, convert
+	  all word detection functions to use the same wrapper function
+	  for ease of maintenance, and make them return more
+	  information.  New functions is_punct_mbchar(),
+	  is_word_mbchar(), do_next_word_void(), do_prev_word_void(),
+	  and do_word_count(); changes to shortcut_init(),
 	  do_next_word(), do_prev_word(), is_whole_word(),
 	  do_statusbar_next_word(), and do_statusbar_prev_word(). (DLR)
 	- Fix #ifdefs so that nano compiles with NANO_SMALL defined and
diff --git a/src/global.c b/src/global.c
index 5c423e3e73ff765904939da9ea041fe092027b4c..7d0dc1726cc571f2511de7f8a76ee71cc590417e 100644
--- a/src/global.c
+++ b/src/global.c
@@ -570,7 +570,7 @@ void shortcut_init(bool unjustify)
 
     sc_init_one(&main_list, NANO_NO_KEY, N_("Prev Word"),
 	IFHELP(nano_prevword_msg, NANO_PREVWORD_KEY), NANO_NO_KEY,
-	NANO_NO_KEY, VIEW, do_prev_word);
+	NANO_NO_KEY, VIEW, do_prev_word_void);
 
     sc_init_one(&main_list, NANO_NO_KEY, N_("Word Count"),
 	IFHELP(nano_wordcount_msg, NANO_WORDCOUNT_KEY), NANO_NO_KEY,
diff --git a/src/nano.c b/src/nano.c
index 16fa6042434a7c2ea74ccc1435f01df7de8de89d..b0f51117e2772f975ab06b10078b462d7eaa9145 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1468,10 +1468,11 @@ void do_enter(void)
 }
 
 #ifndef NANO_SMALL
-/* Move to the next word in the current filestruct.  If allow_update is
- * FALSE, don't update the screen afterward.  Return TRUE if we started
- * on a word, and FALSE otherwise. */
-bool do_next_word(bool allow_update)
+/* Move to the next word in the current filestruct.  If allow_punct is
+ * TRUE, treat punctuation as part of a word.  If allow_update is TRUE,
+ * update the screen afterward.  Return TRUE if we started on a word,
+ * and FALSE otherwise. */
+bool do_next_word(bool allow_punct, bool allow_update)
 {
     size_t pww_save = placewewant;
     const filestruct *current_save = current;
@@ -1491,7 +1492,7 @@ bool do_next_word(bool allow_update)
 
 	/* If we've found it, stop moving forward through the current
 	 * line. */
-	if (!is_word_mbchar(char_mb, TRUE))
+	if (!is_word_mbchar(char_mb, allow_punct))
 	    break;
 
 	/* If we haven't found it, then we've started on a word, so set
@@ -1512,7 +1513,7 @@ bool do_next_word(bool allow_update)
 
 	    /* If we've found it, stop moving forward through the
 	     * current line. */
-	    if (is_word_mbchar(char_mb, TRUE))
+	    if (is_word_mbchar(char_mb, allow_punct))
 		break;
 
 	    current_x += char_mb_len;
@@ -1543,19 +1544,24 @@ bool do_next_word(bool allow_update)
     return started_on_word;
 }
 
+/* Move to the next word in the current filestruct, not counting
+ * punctuation as part of a word, and updating the screen afterward. */
 void do_next_word_void(void)
 {
-    do_next_word(TRUE);
+    do_next_word(FALSE, TRUE);
 }
 
-/* Move to the previous word in the current filestruct. */
-void do_prev_word(void)
+/* Move to the previous word in the current filestruct.  If allow_punct
+ * is TRUE, treat punctuation as part of a word.  If allow_update is
+ * TRUE, update the screen afterward.  Return TRUE if we started on a
+ * word, and FALSE otherwise. */
+bool do_prev_word(bool allow_punct, bool allow_update)
 {
     size_t pww_save = placewewant;
     const filestruct *current_save = current;
     char *char_mb;
     int char_mb_len;
-    bool begin_line = FALSE;
+    bool begin_line = FALSE, started_on_word = FALSE;
 
     assert(current != NULL && current->data != NULL);
 
@@ -1569,9 +1575,13 @@ void do_prev_word(void)
 
 	/* If we've found it, stop moving backward through the current
 	 * line. */
-	if (!is_word_mbchar(char_mb, TRUE))
+	if (!is_word_mbchar(char_mb, allow_punct))
 	    break;
 
+	/* If we haven't found it, then we've started on a word, so set
+	 * started_on_word to TRUE. */
+	started_on_word = TRUE;
+
 	if (current_x == 0)
 	    begin_line = TRUE;
 	else
@@ -1592,7 +1602,7 @@ void do_prev_word(void)
 
 	    /* If we've found it, stop moving backward through the
 	     * current line. */
-	    if (is_word_mbchar(char_mb, TRUE))
+	    if (is_word_mbchar(char_mb, allow_punct))
 		break;
 
 	    if (current_x == 0)
@@ -1631,7 +1641,7 @@ void do_prev_word(void)
 
 	    /* If we've found it, stop moving backward through the
 	     * current line. */
-	    if (!is_word_mbchar(char_mb, TRUE))
+	    if (!is_word_mbchar(char_mb, allow_punct))
 		break;
 
 	    if (current_x == 0)
@@ -1650,8 +1660,19 @@ void do_prev_word(void)
 
     placewewant = xplustabs();
 
-    /* Update the screen. */
-    edit_redraw(current_save, pww_save);
+    /* If allow_update is TRUE, update the screen. */
+    if (allow_update)
+	edit_redraw(current_save, pww_save);
+
+    /* Return whether we started on a word. */
+    return started_on_word;
+}
+
+/* Move to the previous word in the current filestruct, not counting
+ * punctuation as part of a word, and updating the screen afterward. */
+void do_prev_word_void(void)
+{
+    do_prev_word(FALSE, TRUE);
 }
 
 void do_word_count(void)
@@ -1683,11 +1704,13 @@ void do_word_count(void)
     current_x = 0;
     placewewant = 0;
 
-    /* Keep moving to the next word, without updating the screen, until
-     * we reach the end of the file, incrementing the total word count
-     * whenever we're on a word just before moving. */
+    /* Keep moving to the next word (counting punctuation characters as
+     * part of a word so that we match the output of "wc -w"), without
+     * updating the screen, until we reach the end of the file,
+     * incrementing the total word count whenever we're on a word just
+     * before moving. */
     while (current != filebot || current_x != 0) {
-	if (do_next_word(FALSE))
+	if (do_next_word(TRUE, FALSE))
 	    words++;
     }
 
diff --git a/src/proto.h b/src/proto.h
index d6462223572056b31b8b6fc7d9a0860262967558..f6dc2d91e1fdd29f863d7abf606aff73a4c7364d 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -412,9 +412,10 @@ void do_delete(void);
 void do_tab(void);
 void do_enter(void);
 #ifndef NANO_SMALL
-bool do_next_word(bool allow_update);
+bool do_next_word(bool allow_punct, bool allow_update);
 void do_next_word_void(void);
-void do_prev_word(void);
+bool do_prev_word(bool allow_punct, bool allow_update);
+void do_prev_word_void(void);
 void do_word_count(void);
 void do_mark(void);
 #endif
@@ -642,8 +643,8 @@ void do_statusbar_backspace(void);
 void do_statusbar_delete(void);
 void do_statusbar_cut_text(void);
 #ifndef NANO_SMALL
-void do_statusbar_next_word(void);
-void do_statusbar_prev_word(void);
+bool do_statusbar_next_word(bool allow_punct);
+bool do_statusbar_prev_word(bool allow_punct);
 #endif
 void do_statusbar_verbatim_input(bool *got_enter);
 void do_statusbar_output(char *output, size_t output_len, bool
diff --git a/src/winio.c b/src/winio.c
index b34eadd55ccfb8caec2abc00457e9af78f9bd52f..95177fcf9e700468da5c6492c7c3d2d4753cc393 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1770,11 +1770,11 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
 		    break;
 #ifndef NANO_SMALL
 		case NANO_NEXTWORD_KEY:
-		    do_statusbar_next_word();
+		    do_statusbar_next_word(FALSE);
 		    break;
 		case NANO_PREVWORD_KEY:
 		    if (*meta_key == TRUE)
-			do_statusbar_prev_word();
+			do_statusbar_prev_word(FALSE);
 		    break;
 #endif
 		case NANO_VERBATIM_KEY:
@@ -1905,11 +1905,14 @@ void do_statusbar_cut_text(void)
 }
 
 #ifndef NANO_SMALL
-/* Move to the next word at the statusbar prompt. */
-void do_statusbar_next_word(void)
+/* Move to the next word at the statusbar prompt.  If allow_punct is
+ * TRUE, treat punctuation as part of a word.  Return TRUE if we started
+ * on a word, and FALSE otherwise. */
+bool do_statusbar_next_word(bool allow_punct)
 {
     char *char_mb;
     int char_mb_len;
+    bool started_on_word = FALSE;
 
     assert(answer != NULL);
 
@@ -1923,9 +1926,13 @@ void do_statusbar_next_word(void)
 
 	/* If we've found it, stop moving forward through the current
 	 * line. */
-	if (!is_word_mbchar(char_mb, TRUE))
+	if (!is_word_mbchar(char_mb, allow_punct))
 	    break;
 
+	/* If we haven't found it, then we've started on a word, so set
+	 * started_on_word to TRUE. */
+	started_on_word = TRUE;
+
 	statusbar_x += char_mb_len;
     }
 
@@ -1939,21 +1946,26 @@ void do_statusbar_next_word(void)
 
 	/* If we've found it, stop moving forward through the current
 	 * line. */
-	if (is_word_mbchar(char_mb, TRUE))
+	if (is_word_mbchar(char_mb, allow_punct))
 	    break;
 
 	statusbar_x += char_mb_len;
     }
 
     free(char_mb);
+
+    /* Return whether we started on a word. */
+    return started_on_word;
 }
 
-/* Move to the previous word at the statusbar prompt. */
-void do_statusbar_prev_word(void)
+/* Move to the previous word at the statusbar prompt.  If allow_punct is
+ * TRUE, treat punctuation as part of a word.  Return TRUE if we started
+ * on a word, and FALSE otherwise. */
+bool do_statusbar_prev_word(bool allow_punct)
 {
     char *char_mb;
     int char_mb_len;
-    bool begin_line = FALSE;
+    bool begin_line = FALSE, started_on_word = FALSE;
 
     assert(answer != NULL);
 
@@ -1967,9 +1979,13 @@ void do_statusbar_prev_word(void)
 
 	/* If we've found it, stop moving backward through the current
 	 * line. */
-	if (!is_word_mbchar(char_mb, TRUE))
+	if (!is_word_mbchar(char_mb, allow_punct))
 	    break;
 
+	/* If we haven't found it, then we've started on a word, so set
+	 * started_on_word to TRUE. */
+	started_on_word = TRUE;
+
 	if (statusbar_x == 0)
 	    begin_line = TRUE;
 	else
@@ -1989,7 +2005,7 @@ void do_statusbar_prev_word(void)
 
 	/* If we've found it, stop moving backward through the current
 	 * line. */
-	if (is_word_mbchar(char_mb, TRUE))
+	if (is_word_mbchar(char_mb, allow_punct))
 	    break;
 
 	if (statusbar_x == 0)
@@ -2012,7 +2028,7 @@ void do_statusbar_prev_word(void)
 
 	    /* If we've found it, stop moving backward through the
 	     * current line. */
-	    if (!is_word_mbchar(char_mb, TRUE))
+	    if (!is_word_mbchar(char_mb, allow_punct))
 		break;
 
 	    if (statusbar_x == 0)
@@ -2028,8 +2044,11 @@ void do_statusbar_prev_word(void)
     }
 
     free(char_mb);
+
+    /* Return whether we started on a word. */
+    return started_on_word;
 }
-#endif
+#endif /* !NANO_SMALL */
 
 void do_statusbar_verbatim_input(bool *got_enter)
 {