Skip to content

Commit

Permalink
Add history-search function, bound to ctrl-r.
Browse files Browse the repository at this point in the history
Create a very basic "search history" functionality in the line editor.
It uses the current input, and searches backward through history.  If
there is one match, it immediately uses that otherwise it pops up a
simple menu of matches.
  • Loading branch information
kevin8t8 authored and flatcap committed Feb 20, 2018
1 parent f679b1e commit ce17a26
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 0 deletions.
7 changes: 7 additions & 0 deletions doc/manual.xml.head
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,13 @@ color sidebar_divider color8 default
</entry>
<entry>recall next string from history</entry>
</row>
<row>
<entry>^R</entry>
<entry>
<literal>&lt;history-search&gt;</literal>
</entry>
<entry>use current input to search history</entry>
</row>
<row>
<entry>&lt;BackSpace&gt;</entry>
<entry>
Expand Down
9 changes: 9 additions & 0 deletions enter.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,15 @@ int mutt_enter_string_full(char *buf, size_t buflen, int col, int flags, int mul
redraw = MUTT_REDRAW_INIT;
break;

case OP_EDITOR_HISTORY_SEARCH:
state->curpos = state->lastchar;
mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
mutt_history_complete(buf, buflen, hclass);
replace_part(state, 0, buf);
rc = 1;
goto bye;
break;

case OP_EDITOR_BACKSPACE:
if (state->curpos == 0)
BEEP();
Expand Down
1 change: 1 addition & 0 deletions functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ const struct Binding OpEditor[] = { /* map: editor */
{ "buffy-cycle", OP_EDITOR_BUFFY_CYCLE, " " },
{ "history-up", OP_EDITOR_HISTORY_UP, NULL },
{ "history-down", OP_EDITOR_HISTORY_DOWN, NULL },
{ "history-search", OP_EDITOR_HISTORY_SEARCH, "\022" },
{ "transpose-chars", OP_EDITOR_TRANSPOSE_CHARS, NULL },
{ NULL, 0, NULL },
};
Expand Down
113 changes: 113 additions & 0 deletions history.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@
#include "mutt/mutt.h"
#include "history.h"
#include "globals.h"
#include "keymap.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"

Expand All @@ -112,6 +116,14 @@ struct History
short last;
};

static const struct Mapping HistoryHelp[] = {
{ N_("Exit"), OP_EXIT },
{ N_("Select"), OP_GENERIC_SELECT_ENTRY },
{ N_("Search"), OP_SEARCH },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
};

/* global vars used for the string-history routines */

short History; /**< Number of history entries stored in memory */
Expand Down Expand Up @@ -632,3 +644,104 @@ void mutt_hist_save_scratch(enum HistoryClass hclass, const char *str)
* an old garbage value that should be overwritten */
mutt_str_replace(&h->hist[h->last], str);
}

static const char *history_format_str(char *dest, size_t destlen, size_t col, int cols,
char op, const char *src, const char *fmt,
const char *ifstring, const char *elsestring,
unsigned long data, enum FormatFlag flags)
{
char *match = (char *) data;

switch (op)
{
case 's':
mutt_format_s(dest, destlen, fmt, match);
break;
}

return (src);
}

static void history_entry(char *s, size_t slen, struct Menu *m, int num)
{
char *entry = ((char **) m->data)[num];

mutt_expando_format(s, slen, 0, MuttIndexWindow->cols, "%s", history_format_str,
(unsigned long) entry, MUTT_FORMAT_ARROWCURSOR);
}

static void history_menu(char *buf, size_t buflen, char **matches, int match_count)
{
struct Menu *menu;
int done = 0;
char helpstr[LONG_STRING];
char title[STRING];

snprintf(title, sizeof(title), _("History '%s'"), buf);

menu = mutt_new_menu(MENU_GENERIC);
menu->make_entry = history_entry;
menu->title = title;
menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_GENERIC, HistoryHelp);
mutt_push_current_menu(menu);

menu->max = match_count;
menu->data = matches;

while (!done)
{
switch (mutt_menu_loop(menu))
{
case OP_GENERIC_SELECT_ENTRY:
mutt_str_strfcpy(buf, matches[menu->current], buflen);
/* fall through */

case OP_EXIT:
done = 1;
break;
}
}

mutt_pop_current_menu(menu);
mutt_menu_destroy(&menu);
}

static int search_history(char *search_buf, enum HistoryClass hclass, char **matches)
{
struct History *h = get_history(hclass);
int match_count = 0, cur;

if ((History == 0) || !h)
return 0;

cur = h->last;
do
{
cur--;
if (cur < 0)
cur = History;
if (cur == h->last)
break;
if (mutt_str_stristr(h->hist[cur], search_buf))
matches[match_count++] = h->hist[cur];
} while (match_count < History);

return match_count;
}

void mutt_history_complete(char *buf, size_t buflen, enum HistoryClass hclass)
{
char **matches;
int match_count;

matches = mutt_mem_calloc(History, sizeof(char *));
match_count = search_history(buf, hclass, matches);
if (match_count)
{
if (match_count == 1)
mutt_str_strfcpy(buf, matches[0], buflen);
else
history_menu(buf, buflen, matches, match_count);
}
FREE(&matches);
}
1 change: 1 addition & 0 deletions history.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ char *mutt_hist_prev(enum HistoryClass hclass);
void mutt_hist_read_file(void);
void mutt_hist_reset_state(enum HistoryClass hclass);
void mutt_hist_save_scratch(enum HistoryClass hclass, const char *str);
void mutt_history_complete(char *buf, size_t buflen, enum HistoryClass hclass);

#endif /* _MUTT_HISTORY_H */
1 change: 1 addition & 0 deletions opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
_fmt(OP_EDITOR_FORWARD_WORD, N_("move the cursor to the end of the word")) \
_fmt(OP_EDITOR_HISTORY_DOWN, N_("scroll down through the history list")) \
_fmt(OP_EDITOR_HISTORY_UP, N_("scroll up through the history list")) \
_fmt(OP_EDITOR_HISTORY_SEARCH, N_("search through the history list")) \
_fmt(OP_EDITOR_KILL_EOL, N_("delete chars from cursor to end of line")) \
_fmt(OP_EDITOR_KILL_EOW, N_("delete chars from the cursor to the end of the word")) \
_fmt(OP_EDITOR_KILL_LINE, N_("delete all chars on the line")) \
Expand Down

0 comments on commit ce17a26

Please sign in to comment.