edit: Add history buffer search
Ctrl-R can now be used to start history search mode.
This commit is contained in:
parent
42034d6f60
commit
464144a43b
1 changed files with 161 additions and 1 deletions
162
src/utils/edit.c
162
src/utils/edit.c
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue