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);
}