[PATCH] Support additional shell keystrokes.

Ric Claus claus at slac.stanford.edu
Fri Nov 30 23:52:51 UTC 2012


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 files changed, 150 insertions(+), 70 deletions(-)

diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index aea6b98..90bb512 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);
-- 
1.7.1




More information about the devel mailing list