[syslinux] [PATCH 2/3] elflink: Add ctrl-R key bind support
Liu Aleaxander
aleaxander at gmail.com
Sun Oct 3 08:54:05 PDT 2010
This patch would add the CTRL-R key bind support. It would have
the basic feature of the CTRL-R key bind in bash. While, don't
expect it will do exactly like what bash will do.
Signed-off-by: Liu Aleaxander <Aleaxander at gmail.com>
---
core/elflink/cli.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/core/elflink/cli.c b/core/elflink/cli.c
index 9770839..23702d2 100644
--- a/core/elflink/cli.c
+++ b/core/elflink/cli.c
@@ -64,6 +64,65 @@ int mygetkey(clock_t timeout)
}
}
+static const char * cmd_reverse_search(int *cursor)
+{
+ int key;
+ int i = 0;
+ char buf[MAX_CMDLINE_LEN];
+ const char *p = NULL;
+ struct cli_command *last_found;
+ struct cli_command *last_good = NULL;
+
+ last_found = list_entry(cli_history_head.next, typeof(*last_found), list);
+
+ memset(buf, 0, MAX_CMDLINE_LEN);
+
+ printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+ while (1) {
+ key = mygetkey(0);
+
+ if (key == KEY_CTRL('C')) {
+ return NULL;
+ } else if (key == KEY_CTRL('R')) {
+ if (i == 0)
+ continue; /* User typed nothing yet */
+ /* User typed 'CTRL-R' again, so try the next */
+ last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+ } else if (key >= ' ' && key <= 'z') {
+ buf[i++] = key;
+ } else {
+ /* Treat other input chars as terminal */
+ break;
+ }
+
+ while (last_found != &cli_history_head) {
+ p = strstr(last_found->command, buf);
+ if (p)
+ break;
+ last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+ }
+
+ if (!p && !last_good) {
+ return NULL;
+ } else if (!p) {
+ continue;
+ } else {
+ last_good = last_found;
+ *cursor = p - last_good->command;
+ }
+
+ printf("\033[?7l\033[?25l");
+ /* Didn't handle the line wrap case here */
+ printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
+ buf, last_good->command ? : "");
+ printf("\033[K\r");
+ }
+
+ return last_good ? last_good->command : NULL;
+}
+
+
+
const char *edit_cmdline(const char *input, int top /*, int width */ ,
int (*pDraw_Menu) (int, int, int),
void (*show_fkey) (int))
@@ -86,10 +145,9 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
width = 80;
}
- strncpy(cmdline, input, MAX_CMDLINE_LEN);
cmdline[MAX_CMDLINE_LEN - 1] = '\0';
- len = cursor = 0;//strlen(cmdline);
+ len = cursor = 0;
prev_len = 0;
x = y = 0;
@@ -315,6 +373,24 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
}
}
break;
+ case KEY_CTRL('R'):
+ {
+ /*
+ * Handle this case in another function, since it's
+ * a kind of special.
+ */
+ const char *p = cmd_reverse_search(&cursor);
+ if (p) {
+ strcpy(cmdline, p);
+ len = strlen(cmdline);
+ } else {
+ cmdline[0] = '\0';
+ len = 0;
+ }
+ redraw = 1;
+ }
+ break;
+
default:
if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
if (cursor == len) {
--
1.7.2.3
More information about the Syslinux
mailing list