Erik modified rc directly to add a history system.

On Jan 23, 2009, at 5:50 AM, Francisco J Ballesteros wrote:

Russ posted two script called " and "" time ago on this list,
IIRC.


On Fri, Jan 23, 2009 at 11:03 AM, pavel.klinkovsky@gmail.com
<pavel.klinkovsky@gmail.com> wrote:
Hi all,

In Plan9 I missed the simple way to repeat previous (or previous of
previous etc.) command in the terminal.
I prepared a very small (an stupid) program to allow that.

Compile the following source code and run it in that way:
8.out | rc -i

You can insert the commands, and if you want to walk through the
"history", just press CTRL+K (backward) or CTRL+L (foreward).

That is all, folks. ;-)

Pavel


#include <u.h>
#include <libc.h>

enum
{
      KCtrlD = 0x04,
      KCtrlK = 0x0B,
      KCtrlL = 0x0C,
      KDelete = 0x7F,

      MaxLen = 128,
      MaxDepth = 10
};

struct Line
{
      int len;
      char buf[MaxLen];
};
typedef struct Line Line;

void
main(void)
{
      // Console control file descriptor
      int cfd;
      // End flag
      int end = 0;
      // Actual read character
      char c;
      // Array of BackSpaces
      char bs[MaxLen];
      // Array of Lines
      Line line[MaxDepth];
      // Index of actual line
      int act = 0;
      // Index of stored line
      int stored = 0;

      memset(bs, '\b', sizeof(bs));
      memset(line, 0, sizeof(line));

      cfd = open("/dev/consctl", OWRITE);
      if (cfd < 0)
              sysfatal("%r");
      write(cfd, "rawon", 5);

      while (!end) {
              if (read(0, &c, sizeof(c)) < 0)
                      sysfatal("%r");

              switch (c) {
              case KCtrlD:
              case KDelete:
                      end++;
                      break;

              case '\b':
                      if (line[act].len > 0) {
                              line[act].len--;
                              write(2, &c, sizeof(c));
                      }
                      break;

              case '\n':
                      if (line[act].len > 0)
                              write(1, line[act].buf, line[act].len);
                      write(1, &c, sizeof(c));
                      write(2, &c, sizeof(c));
                      act = stored = (act + 1) % MaxDepth;
                      line[act].len = 0;
                      break;

              case KCtrlK:
                      write(2, bs, line[act].len);
                      stored = (stored + MaxDepth - 1) % MaxDepth;
                      line[act] = line[stored];
                      write(2, line[act].buf, line[act].len);
                      break;

              case KCtrlL:
                      write(2, bs, line[act].len);
                      stored = (stored + 1) % MaxDepth;
                      line[act] = line[stored];
                      write(2, line[act].buf, line[act].len);
                      break;

              case -0x11:
                      read(0, &c, sizeof(c));
                      read(0, &c, sizeof(c));
                      break;

              default:
                      if (line[act].len < MaxLen) {
                              line[act].buf[line[act].len++] = c;
                              write(2, &c, sizeof(c));
                      }
                      break;
              }
      }

      close(cfd);

      exits(nil);
}