[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