diff --git a/ChangeLog b/ChangeLog
index ef32227c130967ced41456538d7dffbb04e9420c..13e0b7f4e02590fc22484e2160a85734fe976703 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -111,13 +111,13 @@ CVS code -
 	  chars.c), move_right() (renamed move_mbright() and moved to
 	  chars.c), do_home(), do_verbatim_input(), do_delete(),
 	  do_tab(), do_enter(), indent_length(), do_next_word(),
-	  do_prev_word(), do_input(), do_output(), strstrwrapper(),
-	  get_buffer(), unget_input(), unget_kbinput(), get_input(),
-	  parse_kbinput(), unparse_kbinput(), parse_verbatim_kbinput(),
-	  do_statusbar_input(), do_statusbar_home(),
-	  do_statusbar_verbatim_kbinput(), do_statusbar_output(), and
-	  display_string(); removal of buffer_to_keys() and
-	  keys_to_buffer(). (DLR)
+	  do_prev_word(), do_input(), do_output(), is_whole_word(),
+	  strstrwrapper(), get_buffer(), unget_input(), unget_kbinput(),
+	  get_input(), parse_kbinput(), unparse_kbinput(),
+	  parse_verbatim_kbinput(), do_statusbar_input(),
+	  do_statusbar_home(), do_statusbar_verbatim_kbinput(),
+	  do_statusbar_output(), and display_string(); removal of
+	  buffer_to_keys() and keys_to_buffer(). (DLR)
 	- Add -O/--morespace command line option, plus a corresponding
 	  Meta-O toggle and a "morespace" rcfile option.  When these are
 	  used, the normally-unused blank line below the titlebar will
diff --git a/src/proto.h b/src/proto.h
index 6dc7bcc5c3acd4937de54cf07117f2514235362a..57cd1c7140d15db2a2b568eb36bf1751e1db9ae4 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -483,8 +483,7 @@ void not_found_msg(const char *str);
 void search_abort(void);
 void search_init_globals(void);
 int search_init(bool replacing, bool use_answer);
-bool is_whole_word(int curr_pos, const char *datastr, const char
-	*searchword);
+bool is_whole_word(size_t pos, const char *buf, const char *word);
 bool findnextstr(bool can_display_wrap, bool wholeword, bool
 	no_sameline, const filestruct *begin, size_t beginx, const char
 	*needle, size_t *needle_len);
diff --git a/src/search.c b/src/search.c
index e83edc39c6441e954b4e99a400a871e7a3151763..4e6474817fcf4942643dd6f49a980e6148929654 100644
--- a/src/search.c
+++ b/src/search.c
@@ -265,20 +265,33 @@ int search_init(bool replacing, bool use_answer)
     return 0;
 }
 
-bool is_whole_word(int curr_pos, const char *datastr, const char
-	*searchword)
+bool is_whole_word(size_t pos, const char *buf, const char *word)
 {
-    size_t sln = curr_pos + strlen(searchword);
+    char *p = charalloc(mb_cur_max()), *r = charalloc(mb_cur_max());
+    size_t word_end = pos + strlen(word);
+    bool retval;
 
-    /* Start of line or previous character is not a letter and end of
-     * line or next character is not a letter. */
-    return (curr_pos < 1 || !isalpha(datastr[curr_pos - 1])) &&
-	(sln == strlen(datastr) || !isalpha(datastr[sln]));
+    assert(buf != NULL && pos <= strlen(buf) && word != NULL);
+
+    parse_mbchar(buf + move_mbleft(buf, pos), p, NULL, NULL);
+    parse_mbchar(buf + word_end, r, NULL, NULL);
+
+    /* If we're at the beginning of the line or the character before the
+     * word isn't an alphanumeric character, and if we're at the end of
+     * the line or the character after the word isn't an alphanumeric
+     * character, we have a whole word. */
+    retval = (pos < 1 || !is_alnum_mbchar(p)) &&
+	(word_end == strlen(buf) || !is_alnum_mbchar(r));
+
+    free(p);
+    free(r);
+
+    return retval;
 }
 
-/* Look for needle, starting at current, column current_x.  If
- * no_sameline is TRUE, skip over begin when looking for needle.  begin
- * is the line where we first started searching, at column beginx.  If
+/* Look for needle, starting at (current, current_x).  If no_sameline is
+ * TRUE, skip over begin when looking for needle.  begin is the line
+ * where we first started searching, at column beginx.  If
  * can_display_wrap is TRUE, we put messages on the statusbar, wrap
  * around the file boundaries.  The return value specifies whether we
  * found anything.  If we did, set needle_len to the length of the