diff --git a/ChangeLog b/ChangeLog
index 0d5c82614c4f550b34d9fa576c43fe4d6a82b149..7ebd72994fe1f624e2bb52a2009b0c6dab5a0b55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
 CVS code -
+- General:
+	- Implement filename searches in the file browser.  New
+	  functions filesearch_init(), findnextfile(),
+	  findnextfile_wrap_reset(), filesearch_abort(),
+	  do_filesearch(), do_fileresearch(), do_first_file(),
+	  do_last_file(), do_help_void(), and do_browser_help(); changes
+	  to do_browser(), parse_browser_input(), shortcut_init(),
+	  do_help(), and help_init(). (DLR)
 
 GNU nano 1.3.11 - 2006.03.30
 - General:
diff --git a/TODO b/TODO
index a1bba949e243c5a73bfe393f146486fcc8a9253b..3b545c8f2887b76faede398cc776d8e41ead03d4 100644
--- a/TODO
+++ b/TODO
@@ -5,7 +5,7 @@ For version 1.4:
 - UTF-8 support. [DONE]
 - Support for paragraph searches. [DONE]
 - Support for justifying the entire file at once. [DONE]
-- Support for filename searches in the file browser.
+- Support for filename searches in the file browser. [DONE]
 - Undo/Redo keys?
 - Rebindable keys?
 - Keystroke to implement "Add next sequence as raw" like vi's ^V. [DONE]
diff --git a/src/browser.c b/src/browser.c
index 00c530b1bc498789d3c0cce057f6caf885b5a159..cddc02e2ee1c37624acf22fd0bbd1777cfa89f80 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -40,6 +40,8 @@ static int longest = 0;
 	/* The number of columns in the longest filename in the list. */
 static size_t selected = 0;
 	/* The currently selected filename in the list. */
+static bool search_last_file = FALSE;
+	/* Have we gone past the last file while searching? */
 
 /* Our browser function.  path is the path to start browsing from.
  * Assume path has already been tilde-expanded. */
@@ -187,7 +189,7 @@ char *do_browser(char *path, DIR *dir)
 
 	    case NANO_HELP_KEY:
 #ifndef DISABLE_HELP
-		do_help();
+		do_browser_help();
 		curs_set(0);
 #else
 		nano_disabled_msg();
@@ -251,6 +253,18 @@ char *do_browser(char *path, DIR *dir)
 		total_redraw();
 		break;
 
+	    /* Search for a filename. */
+	    case NANO_WHEREIS_KEY:
+		curs_set(1);
+		do_filesearch();
+		curs_set(0);
+		break;
+
+	    /* Search for another filename. */
+	    case NANO_WHEREIS_NEXT_KEY:
+		do_fileresearch();
+		break;
+
 	    /* Go to a specific directory. */
 	    case NANO_GOTOLINE_KEY:
 		curs_set(1);
@@ -502,6 +516,10 @@ void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key)
 	    case 's':
 		*kbinput = NANO_ENTER_KEY;
 		break;
+	    case 'W':
+	    case 'w':
+		*kbinput = NANO_WHEREIS_KEY;
+		break;
 	}
     }
 }
@@ -592,6 +610,304 @@ void browser_refresh(void)
     wnoutrefresh(edit);
 }
 
+/* Set up the system variables for a filename search.  Return -1 if the
+ * search should be canceled (due to Cancel, a blank search string, or a
+ * failed regcomp()), return 0 on success, and return 1 on rerun calling
+ * program. */
+int filesearch_init(void)
+{
+    int i = 0;
+    char *buf;
+    static char *backupstring = NULL;
+	/* The search string we'll be using. */
+
+    /* If backupstring doesn't exist, initialize it to "". */
+    if (backupstring == NULL)
+	backupstring = mallocstrcpy(NULL, "");
+
+    /* We display the search prompt below.  If the user types a partial
+     * search string and then Replace or a toggle, we will return to
+     * do_search() or do_replace() and be called again.  In that case,
+     * we should put the same search string back up. */
+
+    search_init_globals();
+
+    if (last_search[0] != '\0') {
+	char *disp = display_string(last_search, 0, COLS / 3, FALSE);
+
+	buf = charalloc(strlen(disp) + 7);
+	/* We use (COLS / 3) here because we need to see more on the
+	 * line. */
+	sprintf(buf, " [%s%s]", disp,
+		(strlenpt(last_search) > COLS / 3) ? "..." : "");
+	free(disp);
+    } else
+	buf = mallocstrcpy(NULL, "");
+
+    /* This is now one simple call.  It just does a lot. */
+    i = do_prompt(FALSE,
+#ifndef DISABLE_TABCOMP
+	TRUE,
+#endif
+	whereis_file_list, backupstring,
+#ifndef NANO_TINY
+	&search_history,
+#endif
+	browser_refresh, "%s%s%s%s%s%s", _("Search"),
+#ifndef NANO_TINY
+	/* This string is just a modifier for the search prompt; no
+	 * grammar is implied. */
+	ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") :
+#endif
+	"",
+#ifdef HAVE_REGEX_H
+	/* This string is just a modifier for the search prompt; no
+	 * grammar is implied. */
+	ISSET(USE_REGEXP) ? _(" [Regexp]") :
+#endif
+	"",
+#ifndef NANO_TINY
+	/* This string is just a modifier for the search prompt; no
+	 * grammar is implied. */
+	ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") :
+#endif
+	"", "", buf);
+
+    /* Release buf now that we don't need it anymore. */
+    free(buf);
+
+    free(backupstring);
+    backupstring = NULL;
+
+    /* Cancel any search, or just return with no previous search. */
+    if (i == -1 || (i < 0 && last_search[0] == '\0') ||
+	    (i == 0 && answer[0] == '\0')) {
+	statusbar(_("Cancelled"));
+	return -1;
+    } else {
+	switch (i) {
+	    case -2:		/* It's an empty string. */
+	    case 0:		/* It's a new string. */
+#ifdef HAVE_REGEX_H
+		/* Use last_search if answer is an empty string, or
+		 * answer if it isn't. */
+		if (ISSET(USE_REGEXP) &&
+			regexp_init((i == -2) ? last_search :
+			answer) == 0)
+		    return -1;
+#endif
+		break;
+#ifndef NANO_TINY
+	    case TOGGLE_CASE_KEY:
+		TOGGLE(CASE_SENSITIVE);
+		backupstring = mallocstrcpy(backupstring, answer);
+		return 1;
+	    case TOGGLE_BACKWARDS_KEY:
+		TOGGLE(BACKWARDS_SEARCH);
+		backupstring = mallocstrcpy(backupstring, answer);
+		return 1;
+#endif
+#ifdef HAVE_REGEX_H
+	    case NANO_REGEXP_KEY:
+		TOGGLE(USE_REGEXP);
+		backupstring = mallocstrcpy(backupstring, answer);
+		return 1;
+#endif
+	    default:
+		return -1;
+	}
+    }
+
+    return 0;
+}
+
+/* Look for needle.  If no_sameline is TRUE, skip over selected when
+ * looking for needle.  begin is the location of the filename where we
+ * first started searching.  The return value specifies whether we found
+ * anything. */
+bool findnextfile(bool no_sameline, size_t begin, const char *needle)
+{
+    size_t currselected = selected;
+	/* The location in the current file list of the match we
+	 * find. */
+    const char *rev_start = tail(filelist[currselected]), *found = NULL;
+
+#ifndef NANO_TINY
+    if (ISSET(BACKWARDS_SEARCH))
+	rev_start += strlen(tail(filelist[currselected]));
+#endif
+
+    /* Look for needle in the current filename we're searching. */
+    while (TRUE) {
+	found = strstrwrapper(tail(filelist[currselected]), needle,
+		rev_start);
+
+	/* We've found a potential match.  If we're not allowed to find
+	 * a match on the same filename we started on and this potential
+	 * match is on that line, continue searching. */
+	if (found != NULL && (!no_sameline || currselected != begin))
+	    break;
+
+	/* We've finished processing the filenames, so get out. */
+	if (search_last_file) {
+	    not_found_msg(needle);
+	    return FALSE;
+	}
+
+	/* Move to the previous or next filename in the list.  If we've
+	 * reached the start or end of the list, wrap around. */
+#ifndef NANO_TINY
+	if (ISSET(BACKWARDS_SEARCH)) {
+	    if (currselected > 0)
+		currselected--;
+	    else {
+		currselected = filelist_len - 1;
+		statusbar(_("Search Wrapped"));
+	    }
+	} else {
+#endif
+	    if (currselected < filelist_len - 1)
+		currselected++;
+	    else {
+		currselected = 0;
+		statusbar(_("Search Wrapped"));
+	    }
+#ifndef NANO_TINY
+	}
+#endif
+
+	/* We've reached the original starting file. */
+	if (currselected == begin)
+	    search_last_file = TRUE;
+
+	rev_start = tail(filelist[currselected]);
+#ifndef NANO_TINY
+	if (ISSET(BACKWARDS_SEARCH))
+	    rev_start += strlen(tail(filelist[currselected]));
+#endif
+    }
+
+    /* We've definitely found something. */
+    selected = currselected;
+
+    return TRUE;
+}
+
+/* Clear the flag indicating that a search reached the last file in the
+ * list.  We need to do this just before a new search. */
+void findnextfile_wrap_reset(void)
+{
+    search_last_file = FALSE;
+}
+
+/* Abort the current filename search.  Clean up by setting the current
+ * shortcut list to the browser shortcut list, displaying it, and
+ * decompiling the compiled regular expression we used in the last
+ * search, if any. */
+void filesearch_abort(void)
+{
+    currshortcut = browser_list;
+    bottombars(browser_list);
+#ifdef HAVE_REGEX_H
+    regexp_cleanup();
+#endif
+}
+
+/* Search for a filename. */
+void do_filesearch(void)
+{
+    size_t begin = selected;
+    int i;
+    bool didfind;
+
+    i = filesearch_init();
+    if (i == -1)	/* Cancel, blank search string, or regcomp()
+			 * failed. */
+	filesearch_abort();
+#if !defined(NANO_TINY) || defined(HAVE_REGEX_H)
+    else if (i == 1)	/* Case Sensitive, Backwards, or Regexp search
+			 * toggle. */
+	do_filesearch();
+#endif
+
+    if (i != 0)
+	return;
+
+    /* If answer is now "", copy last_search into answer. */
+    if (answer[0] == '\0')
+	answer = mallocstrcpy(answer, last_search);
+    else
+	last_search = mallocstrcpy(last_search, answer);
+
+#ifndef NANO_TINY
+    /* If answer is not "", add this search string to the search history
+     * list. */
+    if (answer[0] != '\0')
+	update_history(&search_history, answer);
+#endif
+
+    findnextfile_wrap_reset();
+    didfind = findnextfile(FALSE, begin, answer);
+
+    /* Check to see if there's only one occurrence of the string and
+     * we're on it now. */
+    if (selected == begin && didfind) {
+	/* Do the search again, skipping over the current line.  We
+	 * should only end up back at the same position if the string
+	 * isn't found again, in which case it's the only occurrence. */
+	didfind = findnextfile(TRUE, begin, answer);
+	if (selected == begin && !didfind)
+	    statusbar(_("This is the only occurrence"));
+    }
+
+    filesearch_abort();
+}
+
+/* Search for the last filename without prompting. */
+void do_fileresearch(void)
+{
+    size_t begin = selected;
+    bool didfind;
+
+    search_init_globals();
+
+    if (last_search[0] != '\0') {
+#ifdef HAVE_REGEX_H
+	/* Since answer is "", use last_search! */
+	if (ISSET(USE_REGEXP) && regexp_init(last_search) == 0)
+	    return;
+#endif
+
+	findnextfile_wrap_reset();
+	didfind = findnextfile(FALSE, begin, answer);
+
+	/* Check to see if there's only one occurrence of the string and
+	 * we're on it now. */
+	if (selected == begin && didfind) {
+	    /* Do the search again, skipping over the current line.  We
+	     * should only end up back at the same position if the
+	     * string isn't found again, in which case it's the only
+	     * occurrence. */
+	    didfind = findnextfile(TRUE, begin, answer);
+	    if (selected == begin && !didfind)
+		statusbar(_("This is the only occurrence"));
+	}
+    } else
+        statusbar(_("No current search pattern"));
+
+    filesearch_abort();
+}
+
+void do_first_file(void)
+{
+    selected = 0;
+}
+
+void do_last_file(void)
+{
+    selected = filelist_len - 1;
+}
+
 /* Strip one directory from the end of path. */
 void striponedir(char *path)
 {
diff --git a/src/global.c b/src/global.c
index 5b2f235387f316dde2e78bfaea618671534a3ddb..16c4cd85ddd5ccb1d9de9dffb162f17f33732ff5 100644
--- a/src/global.c
+++ b/src/global.c
@@ -153,6 +153,8 @@ shortcut *spell_list = NULL;
 #ifndef DISABLE_BROWSER
 shortcut *browser_list = NULL;
 	/* The file browser shortcut list. */
+shortcut *whereis_file_list = NULL;
+	/* The file browser "Search" shortcut list. */
 shortcut *gotodir_list = NULL;
 	/* The "Go To Directory" shortcut list. */
 #endif
@@ -255,10 +257,14 @@ void shortcut_init(bool unjustify)
     const char *cancel_msg = N_("Cancel");
     const char *get_help_msg = N_("Get Help");
     const char *exit_msg = N_("Exit");
+    const char *whereis_msg = N_("Where Is");
     const char *prev_page_msg = N_("Prev Page");
     const char *next_page_msg = N_("Next Page");
     const char *go_to_line_msg = N_("Go To Line");
     const char *replace_msg = N_("Replace");
+#ifndef NANO_TINY
+    const char *whereis_next_msg = N_("Where Is Next");
+#endif
     const char *refresh_msg = N_("Refresh");
     const char *first_line_msg = N_("First Line");
     const char *last_line_msg = N_("Last Line");
@@ -285,6 +291,8 @@ void shortcut_init(bool unjustify)
 #endif
 #ifndef DISABLE_BROWSER
     const char *to_files_msg = N_("To Files");
+    const char *first_file_msg = N_("First File");
+    const char *last_file_msg = N_("Last File");
 #endif
 #ifndef DISABLE_HELP
     const char *nano_cancel_msg = N_("Cancel the current function");
@@ -406,6 +414,10 @@ void shortcut_init(bool unjustify)
 #endif
 #ifndef DISABLE_BROWSER
     const char *nano_exitbrowser_msg = N_("Exit from the file browser");
+    const char *nano_firstfile_msg =
+	N_("Go to the first file in the list");
+    const char *nano_lastfile_msg =
+	N_("Go to the last file in the list");
     const char *nano_gotodir_msg = N_("Go to directory");
 #endif
 #endif /* !DISABLE_HELP */
@@ -426,7 +438,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -474,7 +486,7 @@ void shortcut_init(bool unjustify)
 	, !ISSET(RESTRICTED) ? do_insertfile_void : nano_disabled_msg);
 
     /* Translators: try to keep this string under 10 characters long. */
-    sc_init_one(&main_list, NANO_WHEREIS_KEY, N_("Where Is"),
+    sc_init_one(&main_list, NANO_WHEREIS_KEY, whereis_msg,
 	IFHELP(nano_whereis_msg, NANO_NO_KEY), NANO_WHEREIS_FKEY,
 	NANO_NO_KEY, VIEW, do_search);
 
@@ -535,7 +547,8 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_mark_msg, NANO_MARK_ALTKEY), NANO_MARK_FKEY,
 	NANO_NO_KEY, VIEW, do_mark);
 
-    sc_init_one(&main_list, NANO_NO_KEY, N_("Where Is Next"),
+    /* Translators: try to keep this string under 16 characters long. */
+    sc_init_one(&main_list, NANO_NO_KEY, whereis_next_msg,
 	IFHELP(nano_whereis_next_msg, NANO_WHEREIS_NEXT_KEY),
 	NANO_WHEREIS_NEXT_FKEY, NANO_NO_KEY, VIEW, do_research);
 #endif
@@ -658,7 +671,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -745,7 +758,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -800,7 +813,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -830,7 +843,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -858,7 +871,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -926,7 +939,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -974,7 +987,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -1030,7 +1043,7 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
@@ -1060,18 +1073,72 @@ void shortcut_init(bool unjustify)
 	IFHELP(nano_nextpage_msg, NANO_NO_KEY), NANO_NEXTPAGE_FKEY,
 	NANO_NO_KEY, VIEW, NULL);
 
+    sc_init_one(&browser_list, NANO_WHEREIS_KEY, whereis_msg,
+	IFHELP(nano_whereis_msg, NANO_NO_KEY), NANO_NO_KEY, NANO_NO_KEY,
+	VIEW, NULL);
+
+    sc_init_one(&browser_list, NANO_NO_KEY, whereis_next_msg,
+	IFHELP(nano_whereis_next_msg, NANO_WHEREIS_NEXT_KEY),
+	NANO_WHEREIS_NEXT_FKEY, NANO_NO_KEY, VIEW, NULL);
+
     /* Translators: try to keep this string under 22 characters long. */
     sc_init_one(&browser_list, NANO_GOTOLINE_KEY, N_("Go To Dir"),
 	IFHELP(nano_gotodir_msg, NANO_GOTOLINE_ALTKEY),
 	NANO_GOTOLINE_FKEY, NANO_NO_KEY, VIEW, NULL);
 
+    free_shortcutage(&whereis_file_list);
+
+    sc_init_one(&whereis_file_list, NANO_HELP_KEY, get_help_msg,
+	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
+	VIEW,
+#ifndef DISABLE_HELP
+	do_browser_help
+#else
+	nano_disabled_msg
+#endif
+	);
+
+    sc_init_one(&whereis_file_list, NANO_CANCEL_KEY, cancel_msg,
+	IFHELP(nano_cancel_msg, NANO_NO_KEY), NANO_NO_KEY, NANO_NO_KEY,
+	VIEW, NULL);
+
+    sc_init_one(&whereis_file_list, NANO_FIRSTFILE_KEY, first_file_msg,
+	IFHELP(nano_firstfile_msg, NANO_NO_KEY), NANO_FIRSTFILE_FKEY,
+	NANO_NO_KEY, VIEW, do_first_file);
+
+    sc_init_one(&whereis_file_list, NANO_LASTFILE_KEY, last_file_msg,
+	IFHELP(nano_lastfile_msg, NANO_NO_KEY), NANO_LASTFILE_FKEY,
+	NANO_NO_KEY, VIEW, do_last_file);
+
+#ifndef NANO_SMALL
+    sc_init_one(&whereis_file_list, NANO_NO_KEY, case_sens_msg,
+	IFHELP(nano_case_msg, TOGGLE_CASE_KEY), NANO_NO_KEY,
+	NANO_NO_KEY, VIEW, NULL);
+
+    sc_init_one(&whereis_file_list, NANO_NO_KEY, backwards_msg,
+	IFHELP(nano_reverse_msg, TOGGLE_BACKWARDS_KEY), NANO_NO_KEY,
+	NANO_NO_KEY, VIEW, NULL);
+#endif
+
+#ifdef HAVE_REGEX_H
+    sc_init_one(&whereis_file_list, NANO_NO_KEY, regexp_msg,
+	IFHELP(nano_regexp_msg, NANO_REGEXP_KEY), NANO_NO_KEY,
+	NANO_NO_KEY, VIEW, NULL);
+#endif
+
+#ifndef NANO_SMALL
+    sc_init_one(&whereis_file_list, NANO_PREVLINE_KEY, history_msg,
+	IFHELP(nano_history_msg, NANO_NO_KEY), NANO_NO_KEY, NANO_NO_KEY,
+	VIEW, NULL);
+#endif
+
     free_shortcutage(&gotodir_list);
 
     sc_init_one(&gotodir_list, NANO_HELP_KEY, get_help_msg,
 	IFHELP(nano_help_msg, NANO_NO_KEY), NANO_HELP_FKEY, NANO_NO_KEY,
 	VIEW,
 #ifndef DISABLE_HELP
-	do_help
+	do_help_void
 #else
 	nano_disabled_msg
 #endif
diff --git a/src/help.c b/src/help.c
index cc70735840eb459bbc98bed2f6b7246125cf1bb3..0d0c2c8b4646ba330499ed39ec7a50b9ae27f735 100644
--- a/src/help.c
+++ b/src/help.c
@@ -32,8 +32,9 @@
 static char *help_text = NULL;
 	/* The text displayed in the help window. */
 
-/* Our dynamic, shortcut-list-compliant help function. */
-void do_help(void)
+/* Our dynamic, shortcut-list-compliant help function.  refresh_func is
+ * the function we will call to refresh the edit window.*/
+void do_help(void (*refresh_func)(void))
 {
     int line = 0;
 	/* The line number in help_text of the first displayed help
@@ -159,7 +160,7 @@ void do_help(void)
 	bottombars(currshortcut);
 
     curs_set(1);
-    edit_refresh();
+    refresh_func();
 
     /* The help_init() at the beginning allocated help_text.  Since 
      * help_text has now been written to the screen, we don't need it
@@ -168,6 +169,20 @@ void do_help(void)
     help_text = NULL;
 }
 
+/* Start the help browser for the edit window. */
+void do_help_void(void)
+{
+    do_help(&edit_refresh);
+}
+
+#ifndef DISABLE_BROWSER
+/* Start the help browser for the file browser. */
+void do_browser_help(void)
+{
+    do_help(&browser_refresh);
+}
+#endif
+
 /* This function allocates help_text, and stores the help string in it. 
  * help_text should be NULL initially. */
 void help_init(void)
@@ -256,6 +271,19 @@ void help_init(void)
 		"in the file browser:\n\n");
 	htx[1] = NULL;
 	htx[2] = NULL;
+    } else if (currshortcut == whereis_file_list) {
+	htx[0] = N_("Browser Search Command Help Text\n\n "
+		"Enter the words or characters you would like to "
+		"search for, and then press Enter.  If there is a "
+		"match for the text you entered, the screen will be "
+		"updated to the location of the nearest match for the "
+		"search string.\n\n The previous search string will be "
+		"shown in brackets after the search prompt.  Hitting "
+		"Enter without entering any text will perform the "
+		"previous search.\n\n ");
+	htx[1] = N_("The following function keys are available in "
+		"Browser Search mode:\n\n");
+	htx[2] = NULL;
     } else if (currshortcut == gotodir_list) {
 	htx[0] = N_("Browser Go To Directory Help Text\n\n "
 		"Enter the name of the directory you would like to "
diff --git a/src/nano.h b/src/nano.h
index 99521e9f5a7fe6a709983b41ee7647a3ccd18a98..829b8473543eb83f3fcaf3ee8525afcf9d3df4bf 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -495,8 +495,12 @@ typedef struct rcoption {
 #define NANO_SPELL_FKEY		KEY_F(12)
 #define NANO_FIRSTLINE_KEY	NANO_PREVPAGE_KEY
 #define NANO_FIRSTLINE_FKEY	NANO_PREVPAGE_FKEY
+#define NANO_FIRSTFILE_KEY	NANO_FIRSTLINE_KEY
+#define NANO_FIRSTFILE_FKEY	NANO_FIRSTLINE_FKEY
 #define NANO_LASTLINE_KEY	NANO_NEXTPAGE_KEY
 #define NANO_LASTLINE_FKEY	NANO_NEXTPAGE_FKEY
+#define NANO_LASTFILE_KEY	NANO_LASTLINE_KEY
+#define NANO_LASTFILE_FKEY	NANO_LASTLINE_FKEY
 #define NANO_REFRESH_KEY	NANO_CONTROL_L
 #define NANO_JUSTIFY_KEY	NANO_CONTROL_J
 #define NANO_JUSTIFY_FKEY	KEY_F(4)
diff --git a/src/proto.h b/src/proto.h
index b2d03191911be4a6ecba10280a95427b77b06fd2..78caf80a6b095a33807004b4b979fc73f6100190 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -104,6 +104,7 @@ extern shortcut *spell_list;
 #endif
 #ifndef DISABLE_BROWSER
 extern shortcut *browser_list;
+extern shortcut *whereis_file_list;
 extern shortcut *gotodir_list;
 #endif
 
@@ -142,6 +143,14 @@ char *do_browse_from(const char *inpath);
 void browser_init(const char *path, DIR *dir);
 void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key);
 void browser_refresh(void);
+int filesearch_init(void);
+bool findnextfile(bool no_sameline, size_t begin, const char *needle);
+void findnextfile_wrap_reset(void);
+void filesearch_abort(void);
+void do_filesearch(void);
+void do_fileresearch(void);
+void do_first_file(void);
+void do_last_file(void);
 void striponedir(char *path);
 #endif
 
@@ -330,7 +339,11 @@ void thanks_for_all_the_fish(void);
 
 /* Public functions in help.c. */
 #ifndef DISABLE_HELP
-void do_help(void);
+void do_help(void (*refresh_func)(void));
+void do_help_void(void);
+#ifndef DISABLE_BROWSER
+void do_browser_help(void);
+#endif
 void help_init(void);
 size_t help_line_len(const char *ptr);
 #endif