From mboxrd@z Thu Jan 1 00:00:00 1970 To: 9fans@9fans.net Date: Fri, 23 Jan 2009 10:03:49 +0000 From: "pavel.klinkovsky@gmail.com" Message-ID: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: [9fans] Small program "PlanKey" (paraphrase of DOSKey) Topicbox-Message-UUID: 854012d2-ead4-11e9-9d60-3106f5b1d025 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 #include 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); }