diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in index c57c3f22ca..0b6ae5178c 100644 --- a/doc/man/mc.1.in +++ b/doc/man/mc.1.in @@ -565,6 +565,18 @@ or keys can be used to correct typing mistakes. If C\-s is pressed again, the next match is searched for. .P +The +.I SearchNext +and +.I SearchPrev +panel actions can be used to cycle through files matching the current +search pattern, wrapping around at the beginning or end of the list. +By default, +.I SearchNext +is bound to C\-s (same as repeating the search). +.I SearchPrev +has no default binding but can be configured in the keymap file. +.P If quick search is started with double pressing of C\-s, the previous quick search pattern will be used for current search. .P diff --git a/lib/keybind.c b/lib/keybind.c index 194f3ecbc7..7667d49a85 100644 --- a/lib/keybind.c +++ b/lib/keybind.c @@ -98,6 +98,8 @@ static name_keymap_t command_names[] = { ADD_KEYMAP_NAME (EditUserMenu), ADD_KEYMAP_NAME (Search), ADD_KEYMAP_NAME (SearchContinue), + ADD_KEYMAP_NAME (SearchNext), + ADD_KEYMAP_NAME (SearchPrev), ADD_KEYMAP_NAME (Replace), ADD_KEYMAP_NAME (ReplaceContinue), ADD_KEYMAP_NAME (Help), diff --git a/lib/keybind.h b/lib/keybind.h index 28be23559e..5d460badad 100644 --- a/lib/keybind.h +++ b/lib/keybind.h @@ -80,6 +80,8 @@ enum CK_Replace, CK_ReplaceContinue, CK_SearchStop, + CK_SearchNext, + CK_SearchPrev, CK_Help, CK_Edit, CK_EditNew, diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 049b56be8e..2ded183938 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -3530,11 +3530,81 @@ panel_execute_cmd (WPanel *panel, long command) { int res = MSG_HANDLED; - if (command != CK_Search) + if (command != CK_Search && command != CK_SearchNext && command != CK_SearchPrev) stop_search (panel); switch (command) { + case CK_SearchNext: + case CK_SearchPrev: + if (panel->quick_search.active) + { + int direction = (command == CK_SearchNext) ? 1 : -1; + int start = panel->current + direction; + int i, found = -1; + gboolean wrapped = FALSE; + char *reg_exp, *esc_str; + mc_search_t *search; + + if (panel->quick_search.buffer->len == 0) + break; + + reg_exp = g_strdup_printf ("%s*", panel->quick_search.buffer->str); + esc_str = str_escape (reg_exp, -1, ",|\\{}[]", TRUE); + search = mc_search_new (esc_str, NULL); + search->search_type = MC_SEARCH_T_GLOB; + search->is_entire_line = TRUE; + + switch (panels_options.qsearch_mode) + { + case QSEARCH_CASE_SENSITIVE: + search->is_case_sensitive = TRUE; + break; + case QSEARCH_CASE_INSENSITIVE: + search->is_case_sensitive = FALSE; + break; + default: + search->is_case_sensitive = panel->sort_info.case_sensitive; + break; + } + + for (i = start; !wrapped || i != start; i += direction) + { + if (i >= panel->dir.len) + { + i = 0; + if (wrapped) + break; + wrapped = TRUE; + } + if (i < 0) + { + i = panel->dir.len - 1; + if (wrapped) + break; + wrapped = TRUE; + } + if (mc_search_run (search, panel->dir.list[i].fname->str, 0, + panel->dir.list[i].fname->len, NULL)) + { + found = i; + break; + } + } + + mc_search_free (search); + g_free (reg_exp); + g_free (esc_str); + + if (found >= 0) + { + unselect_item (panel); + panel->current = found; + select_item (panel); + widget_draw (WIDGET (panel)); + } + } + break; case CK_Up: case CK_Down: case CK_Left: diff --git a/src/keymap.c b/src/keymap.c index 35ef2759eb..05d4322961 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -226,6 +226,8 @@ static const global_keymap_ini_t default_panel_keymap[] = { { "PageUp", "pgup; alt-v" }, { "SelectCodepage", "alt-e" }, { "Search", "ctrl-s; alt-s" }, + { "SearchNext", "ctrl-s" }, + { "SearchPrev", "" }, { "PanelOtherSync", "alt-i" }, { NULL,