edit: Add history buffer search

Ctrl-R can now be used to start history search mode.
This commit is contained in:
Jouni Malinen 2010-11-20 17:55:35 +02:00
parent 42034d6f60
commit 464144a43b

View file

@ -37,6 +37,9 @@ static char ** (*edit_completion_cb)(void *ctx, const char *cmd, int pos) =
static struct termios prevt, newt; static struct termios prevt, newt;
#define CLEAR_END_LINE "\e[K"
void edit_clear_line(void) void edit_clear_line(void)
{ {
int i; int i;
@ -785,13 +788,169 @@ static enum edit_key_code edit_read_key(int sock)
} }
static char search_buf[21];
static int search_skip;
static char * search_find(void)
{
int pos = history_pos;
size_t len = os_strlen(search_buf);
int skip = search_skip;
if (len == 0)
return NULL;
for (;;) {
if (pos == 0)
pos = CMD_HISTORY_LEN - 1;
else
pos--;
if (pos == history_pos) {
search_skip = 0;
return NULL;
}
if (os_strstr(history_buf[pos], search_buf)) {
if (skip == 0)
return history_buf[pos];
skip--;
}
}
}
static void search_redraw(void)
{
char *match = search_find();
printf("\rsearch '%s': %s" CLEAR_END_LINE,
search_buf, match ? match : "");
printf("\rsearch '%s", search_buf);
fflush(stdout);
}
static void search_start(void)
{
edit_clear_line();
search_buf[0] = '\0';
search_skip = 0;
search_redraw();
}
static void search_clear(void)
{
search_redraw();
printf("\r" CLEAR_END_LINE);
}
static void search_stop(void)
{
char *match = search_find();
search_buf[0] = '\0';
search_clear();
if (match) {
os_strlcpy(cmdbuf, match, CMD_BUF_LEN);
cmdbuf_len = os_strlen(cmdbuf);
cmdbuf_pos = cmdbuf_len;
}
edit_redraw();
}
static void search_cancel(void)
{
search_buf[0] = '\0';
search_clear();
edit_redraw();
}
static void search_backspace(void)
{
size_t len;
len = os_strlen(search_buf);
if (len == 0)
return;
search_buf[len - 1] = '\0';
search_skip = 0;
search_redraw();
}
static void search_next(void)
{
search_skip++;
search_find();
search_redraw();
}
static void search_char(char c)
{
size_t len;
len = os_strlen(search_buf);
if (len == sizeof(search_buf) - 1)
return;
search_buf[len] = c;
search_buf[len + 1] = '\0';
search_skip = 0;
search_redraw();
}
static enum edit_key_code search_key(enum edit_key_code c)
{
switch (c) {
case EDIT_KEY_ENTER:
case EDIT_KEY_CTRL_J:
case EDIT_KEY_LEFT:
case EDIT_KEY_RIGHT:
case EDIT_KEY_HOME:
case EDIT_KEY_END:
case EDIT_KEY_CTRL_A:
case EDIT_KEY_CTRL_E:
search_stop();
return c;
case EDIT_KEY_DOWN:
case EDIT_KEY_UP:
search_cancel();
return EDIT_KEY_EOF;
case EDIT_KEY_CTRL_H:
case EDIT_KEY_BACKSPACE:
search_backspace();
break;
case EDIT_KEY_CTRL_R:
search_next();
break;
default:
if (c >= 32 && c <= 255)
search_char(c);
break;
}
return EDIT_KEY_NONE;
}
static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx) static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
{ {
static int last_tab = 0; static int last_tab = 0;
static int search = 0;
enum edit_key_code c; enum edit_key_code c;
c = edit_read_key(sock); c = edit_read_key(sock);
if (search) {
c = search_key(c);
if (c == EDIT_KEY_NONE)
return;
search = 0;
if (c == EDIT_KEY_EOF)
return;
}
if (c != EDIT_KEY_TAB && c != EDIT_KEY_NONE) if (c != EDIT_KEY_TAB && c != EDIT_KEY_NONE)
last_tab = 0; last_tab = 0;
@ -867,7 +1026,8 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
edit_redraw(); edit_redraw();
break; break;
case EDIT_KEY_CTRL_R: case EDIT_KEY_CTRL_R:
/* TODO: search history */ search = 1;
search_start();
break; break;
case EDIT_KEY_CTRL_U: case EDIT_KEY_CTRL_U:
clear_left(); clear_left();