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;
|
||||
|
||||
|
||||
#define CLEAR_END_LINE "\e[K"
|
||||
|
||||
|
||||
void edit_clear_line(void)
|
||||
{
|
||||
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 int last_tab = 0;
|
||||
static int search = 0;
|
||||
enum edit_key_code c;
|
||||
|
||||
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)
|
||||
last_tab = 0;
|
||||
|
||||
|
@ -867,7 +1026,8 @@ static void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
|
|||
edit_redraw();
|
||||
break;
|
||||
case EDIT_KEY_CTRL_R:
|
||||
/* TODO: search history */
|
||||
search = 1;
|
||||
search_start();
|
||||
break;
|
||||
case EDIT_KEY_CTRL_U:
|
||||
clear_left();
|
||||
|
|
Loading…
Reference in a new issue