From 22e983771f93d99e547030675c59a9b6bc5e5143 Mon Sep 17 00:00:00 2001 From: Ric Claus Date: Fri, 30 Nov 2012 15:52:51 -0800 Subject: Support additional shell keystrokes. Emacs style keystrokes Ctrl-B, F, G, P, N, T and U are now supported as they are in bash. Also, commands invoked from the history are moved up in the history buffer when they are executed. Thus, the most recently executed command is always just one up-arrow (or Ctrl-P) keystroke away. --- cpukit/libmisc/shell/shell.c | 220 +++++++++++++++++++++++++++++-------------- 1 file changed, 150 insertions(+), 70 deletions(-) (limited to 'cpukit/libmisc/shell/shell.c') diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index aea6b98d1c..90bb51253e 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -173,70 +173,24 @@ static int rtems_shell_line_editor( break; case RTEMS_SHELL_KEYS_LARROW: - if (col > 0) - { - col--; - if (output) - fputc('\b', out); - } + c = 2; + extended_key = 0; break; - case RTEMS_SHELL_KEYS_RARROW: - if ((col < size) && (line[col] != '\0')) - { - if (output) - fprintf(out, "%c", line[col]); - col++; - } - break; + case RTEMS_SHELL_KEYS_RARROW: + c = 6; + extended_key = 0; + break; case RTEMS_SHELL_KEYS_UARROW: - if ((cmd >= (count - 1)) || (strlen(cmds[cmd + 1]) == 0)) { - if (output) - fputc('\x7', out); - break; - } - - up = 1; + c = 16; + extended_key = 0; + break; - /* drop through */ case RTEMS_SHELL_KEYS_DARROW: - - { - int last_cmd = cmd; - int clen = strlen (line); - - if (prompt) - clen += strlen(prompt); - - if (up) { - cmd++; - } else { - if (cmd < 0) { - if (output) - fprintf(out, "\x7"); - break; - } - else - cmd--; - } - - if ((last_cmd < 0) || (strcmp(cmds[last_cmd], line) != 0)) - memcpy (new_line, line, size); - - if (cmd < 0) - memcpy (line, new_line, size); - else - memcpy (line, cmds[cmd], size); - - col = strlen (line); - - if (output) { - fprintf(out,"\r%*c", clen, ' '); - fprintf(out,"\r%s%s", prompt, line); - } - } - break; + c = 14; + extended_key = 0; + break; case RTEMS_SHELL_KEYS_DEL: if (line[col] != '\0') @@ -258,11 +212,11 @@ static int rtems_shell_line_editor( break; } } - else + if (!extended_key) { switch (c) { - case 1:/*Control-a*/ + case 1: /*Control-a*/ if (output) { if (prompt) fprintf(out,"\r%s", prompt); @@ -270,13 +224,59 @@ static int rtems_shell_line_editor( col = 0; break; - case 5:/*Control-e*/ + case 2: /* Control-B */ + if (col > 0) + { + col--; + if (output) + fputc('\b', out); + } + break; + + case 4: /* Control-D */ + if (strlen(line)) { + if (col < strlen(line)) { + strcpy (line + col, line + col + 1); + if (output) { + int bs; + fprintf(out,"%s \b", line + col); + for (bs = 0; bs < ((int) strlen (line) - col); bs++) + fputc('\b', out); + } + } + break; + } + /* Fall through */ + + case EOF: + if (output) + fputc('\n', out); + return -2; + + case 5: /*Control-e*/ if (output) fprintf(out, "%s", line + col); col = (int) strlen (line); break; - case 11:/*Control-k*/ + case 6: /* Control-F */ + if ((col < size) && (line[col] != '\0')) { + if (output) + fputc(line[col], out); + col++; + } + break; + + case 7: /* Control-G */ + if (output) { + fprintf(out,"\r%s%*c", prompt, strlen (line), ' '); + fprintf(out,"\r%s\x7", prompt); + } + memset (line, '\0', strlen(line)); + col = 0; + break; + + case 11: /*Control-k*/ if (line[col]) { if (output) { int end = strlen(line); @@ -289,14 +289,6 @@ static int rtems_shell_line_editor( } break; - case 0x04:/*Control-d*/ - if (strlen(line)) - break; - case EOF: - if (output) - fputc('\n', out); - return -2; - case '\f': if (output) { int end; @@ -345,11 +337,99 @@ static int rtems_shell_line_editor( memmove(cmds[1], cmds[0], (count - 1) * size); memmove (cmds[0], line, size); cmd = 0; + } else { + if ((cmd > 1) && (strcmp(line, cmds[cmd]) == 0)) { + memmove(cmds[1], cmds[0], cmd * size); + memmove (cmds[0], line, size); + cmd = 0; + } } } } return cmd; + case 16: /* Control-P */ + if ((cmd >= (count - 1)) || (strlen(cmds[cmd + 1]) == 0)) { + if (output) + fputc('\x7', out); + break; + } + + up = 1; + /* drop through */ + + case 14: /* Control-N */ + { + int last_cmd = cmd; + int clen = strlen (line); + + if (prompt) + clen += strlen(prompt); + + if (up) { + cmd++; + } else { + if (cmd < 0) { + if (output) + fprintf(out, "\x7"); + break; + } + else + cmd--; + } + + if ((last_cmd < 0) || (strcmp(cmds[last_cmd], line) != 0)) + memcpy (new_line, line, size); + + if (cmd < 0) + memcpy (line, new_line, size); + else + memcpy (line, cmds[cmd], size); + + col = strlen (line); + + if (output) { + fprintf(out,"\r%s%*c", prompt, clen, ' '); + fprintf(out,"\r%s%s", prompt, line); + } + } + break; + + case 20: /* Control-T */ + if (col > 0) + { + char tmp; + if (col == strlen(line)) { + col--; + if (output) + fprintf(out,"\b"); + } + tmp = line[col]; + line[col] = line[col - 1]; + line[col - 1] = tmp; + if (output) + fprintf(out,"\b%c%c", line[col - 1], line[col]); + col++; + } else { + if (output) + fputc('\x7', out); + } + break; + + case 21: /* Control-U */ + if (col > 0) + { + int clen = strlen (line); + + strcpy (line, line + col); + if (output) { + fprintf(out,"\r%s%*c", prompt, clen, ' '); + fprintf(out,"\r%s%s", prompt, line); + } + col = 0; + } + break; + default: if ((col < (size - 1)) && (c >= ' ') && (c <= '~')) { int end = strlen (line); -- cgit v1.2.3