Add rudimentary incremental search facility

This commit is contained in:
Přemysl Eric Janouch 2021-12-08 16:14:00 +01:00
parent 5aa07fd8af
commit 4e3596db35
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 53 additions and 2 deletions

View File

@ -38,6 +38,7 @@ CHOOSE, Choose item
DELETE, Delete item DELETE, Delete item
UP, Go up a level UP, Go up a level
MULTISELECT, Toggle multiselect MULTISELECT, Toggle multiselect
INCREMENTAL_SEARCH, Incremental search
SCROLL_UP, Scroll up SCROLL_UP, Scroll up
SCROLL_DOWN, Scroll down SCROLL_DOWN, Scroll down

View File

@ -2319,7 +2319,7 @@ app_setvol (int value)
} }
static void static void
app_on_editor_end (bool confirmed) app_on_mpd_command_editor_end (bool confirmed)
{ {
struct mpd_client *c = &g.client; struct mpd_client *c = &g.client;
if (!confirmed) if (!confirmed)
@ -2334,6 +2334,49 @@ app_on_editor_end (bool confirmed)
mpd_client_idle (c, 0); mpd_client_idle (c, 0);
} }
static size_t
incremental_search_match (const ucs4_t *needle, size_t len,
const struct row_buffer *row)
{
// TODO: case-insensitive search, wilcards, regexps, something easy to use
size_t i = 0;
for (; i < len && i < row->chars_len; i++)
if (needle[i] != row->chars[i].c)
break;
return i;
}
static void
incremental_search_on_changed (void)
{
struct tab *tab = g.active_tab;
if (!tab->item_count)
return;
size_t best = 0, current = 0, index = MAX (tab->item_selected, 0), i = 0;
while (i++ < tab->item_count)
{
struct row_buffer buf = row_buffer_make ();
tab->on_item_draw (index, &buf, COLS);
current = incremental_search_match (g.editor.line, g.editor.len, &buf);
row_buffer_free (&buf);
if (best < current)
{
best = current;
tab->item_selected = index;
app_move_selection (0);
}
index = (index + 1) % tab->item_count;
}
}
static void
incremental_search_on_end (bool confirmed)
{
(void) confirmed;
// Required callback, nothing to do here.
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static bool static bool
@ -2376,7 +2419,7 @@ app_process_action (enum action action)
return true; return true;
case ACTION_MPD_COMMAND: case ACTION_MPD_COMMAND:
line_editor_start (&g.editor, ':'); line_editor_start (&g.editor, ':');
g.editor.on_end = app_on_editor_end; g.editor.on_end = app_on_mpd_command_editor_end;
app_invalidate (); app_invalidate ();
return true; return true;
default: default:
@ -2393,6 +2436,12 @@ app_process_action (enum action action)
else else
tab->item_mark = tab->item_selected; tab->item_mark = tab->item_selected;
return true; return true;
case ACTION_INCREMENTAL_SEARCH:
line_editor_start (&g.editor, '/');
g.editor.on_changed = incremental_search_on_changed;
g.editor.on_end = incremental_search_on_end;
app_invalidate ();
return true;
case ACTION_TAB_LAST: case ACTION_TAB_LAST:
if (!g.last_tab) if (!g.last_tab)
@ -2683,6 +2732,7 @@ g_normal_defaults[] =
{ "M-Up", ACTION_UP }, { "M-Up", ACTION_UP },
{ "Backspace", ACTION_UP }, { "Backspace", ACTION_UP },
{ "v", ACTION_MULTISELECT }, { "v", ACTION_MULTISELECT },
{ "C-s", ACTION_INCREMENTAL_SEARCH },
{ "/", ACTION_MPD_SEARCH }, { "/", ACTION_MPD_SEARCH },
{ "a", ACTION_MPD_ADD }, { "a", ACTION_MPD_ADD },
{ "r", ACTION_MPD_REPLACE }, { "r", ACTION_MPD_REPLACE },