home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <signal.h>
- #include <curses.h>
- #include <strings.h>
-
- #define HISTLEN 20
- #define LINELEN 500
- #define PRLINELEN 1000
-
- outc(ch)
- char ch;
- {
- putc(ch,stderr);
- }
-
- sigpipe()
- {
- close(0); /* guaranteeing that the next character we read will be an EOF */
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- char bp[1024];
- char ts[256];
- char fs[256];
- char ce[256];
- char us[256];
- char ue[256];
- char *cptr;
- char errbuf[BUFSIZ];
- char history[HISTLEN][LINELEN];
- char prhistory[HISTLEN][PRLINELEN];
- char ahistory[HISTLEN][LINELEN];
- char aprhistory[HISTLEN][PRLINELEN];
- int histpos = 0;
- int minhistpos = 0;
- int temphistpos;
- char *line;
- char *linepr;
- char *aline;
- char *alinepr;
- int ch;
- char *chpr;
- int x;
- int xpr;
- int y;
- int ypr;
- int flagcharmode = 0;
- int co;
- int i;
-
- signal(SIGPIPE,sigpipe);
- setbuf(stderr,errbuf);
-
- tgetent(bp,getenv("TERM"));
- cptr = ts;
- if (!tgetstr("ts",&cptr))
- ; /*XXX*/
- cptr = fs;
- if (!tgetstr("fs",&cptr))
- ; /*XXX*/
- cptr = ce;
- if (!tgetstr("ce",&cptr))
- ; /*XXX*/
- cptr = us;
- if (!tgetstr("us",&cptr))
- ; /*XXX*/
- cptr = ue;
- if (!tgetstr("ue",&cptr))
- ; /*XXX*/
- co = tgetnum("co");
- #define TS tputs(ts,1,outc)
- #define CE tputs(ce,1,outc)
- #define FS tputs(fs,1,outc)
- #define US tputs(us,1,outc)
- #define UE tputs(ue,1,outc)
-
- for (;;)
- if (flagcharmode)
- {
- if ((ch = getchar()) == EOF)
- break;
- if (ch == 0001)
- flagcharmode = 0;
- else
- {
- putchar(ch);
- fflush(stdout);
- }
- }
- else
- {
- line = history[histpos];
- aline = ahistory[histpos];
- linepr = prhistory[histpos];
- alinepr = aprhistory[histpos];
- temphistpos = histpos;
- TS; CE; US; putc(' ',stderr); UE; FS; fflush(stderr);
- x = xpr = 0;
- line[x] = linepr[xpr] = '\0';
- y = ypr = 0;
- aline[y] = alinepr[ypr] = '\0';
- while ((ch = getchar()) != '\n')
- {
- if ((temphistpos != histpos) && (ch != 2) && (ch != 6))
- {
- strcpy(history[histpos],line); line = history[histpos];
- strcpy(ahistory[histpos],aline); aline = ahistory[histpos];
- strcpy(prhistory[histpos],linepr); linepr = prhistory[histpos];
- strcpy(aprhistory[histpos],alinepr); alinepr = aprhistory[histpos];
- temphistpos = histpos;
- }
- if (ch == 4)
- break;
- if (ch == EOF)
- break;
- if (ch == '\r')
- {
- ch = '\n';
- break;
- }
- if (ch == 1)
- {
- flagcharmode = 1;
- break;
- }
- switch(ch)
- {
- case 6: if (temphistpos != histpos)
- {
- temphistpos++;
- if (temphistpos == HISTLEN)
- temphistpos = 0;
- }
- line = history[temphistpos];
- aline = ahistory[temphistpos];
- linepr = prhistory[temphistpos];
- alinepr = aprhistory[temphistpos];
- x = strlen(line);
- y = strlen(aline);
- xpr = strlen(linepr);
- ypr = strlen(alinepr);
- break;
- case 2: if (temphistpos != minhistpos)
- {
- if (temphistpos == 0)
- temphistpos = HISTLEN;
- temphistpos--;
- }
- line = history[temphistpos];
- aline = ahistory[temphistpos];
- linepr = prhistory[temphistpos];
- alinepr = aprhistory[temphistpos];
- x = strlen(line);
- y = strlen(aline);
- xpr = strlen(linepr);
- ypr = strlen(alinepr);
- break;
- case 21: x = xpr = 0;
- line[x] = linepr[xpr] = '\0';
- break;
- case 23: while (x && (line[x - 1] == ' '))
- {
- x--;
- xpr--;
- }
- while (x && (line[x - 1] != ' '))
- {
- x--;
- chpr = unctrl(line[x]);
- while (*(chpr++))
- xpr--;
- }
- linepr[xpr] = '\0';
- line[x] = '\0';
- break;
- case '\b': if (!x)
- break;
- x--;
- aline[y] = line[x];
- y++;
- chpr = unctrl(line[x]);
- while (*(chpr++))
- {
- xpr--;
- alinepr[ypr] = linepr[xpr];
- ypr++;
- }
- linepr[xpr] = '\0';
- line[x] = '\0';
- alinepr[ypr] = '\0';
- aline[y] = '\0';
- break;
- case 12: if (!y)
- break;
- y--;
- line[x] = aline[y];
- x++;
- chpr = unctrl(aline[y]);
- while (*(chpr++))
- {
- ypr--;
- linepr[xpr] = alinepr[ypr];
- xpr++;
- }
- linepr[xpr] = '\0';
- line[x] = '\0';
- alinepr[ypr] = '\0';
- aline[y] = '\0';
- break;
- case 127: if (!x)
- break;
- x--;
- chpr = unctrl(line[x]);
- while (*(chpr++))
- xpr--;
- linepr[xpr] = '\0';
- line[x] = '\0';
- break;
- case 22: ch = getchar();
- case 0: ; /*XXX*/
- default: if ((x == LINELEN - 1) || (xpr == PRLINELEN - 1))
- {
- putchar(7);
- break;
- }
- line[x++] = ch;
- line[x] = '\0';
- chpr = unctrl(ch);
- while(*chpr)
- linepr[xpr++] = *(chpr++);
- linepr[xpr] = '\0';
- }
- TS;
- if (ypr)
- {
- if (xpr > co - 7)
- {
- fputs("<- ",stderr); fputs(linepr + xpr - co + 10,stderr);
- US; putc(aline[ypr - 1],stderr); UE;
- if (ypr != 1)
- {
- putc(' ',stderr); putc('-',stderr); putc('>',stderr);
- }
- }
- else
- {
- fputs(linepr,stderr);
- US; putc(aline[ypr - 1],stderr); UE;
- for (i = ypr - 2;(i >= 0) && (i >= xpr + ypr - co + 6);i--)
- putc(aline[i],stderr);
- if (i != -1)
- {
- putc(' ',stderr); putc('-',stderr); putc('>',stderr);
- }
- }
- }
- else
- {
- if (xpr > co - 6)
- { fputs("<- ",stderr); fputs(linepr + xpr - co + 9,stderr); }
- else
- { fputs(linepr,stderr); }
- US; putc(' ',stderr); UE;
- }
- CE; FS; fflush(stderr);
- }
- if ((ch == EOF) || (ch == 4))
- {
- for (i = 0;i < x;i++)
- putchar(line[i]);
- for (i = y - 1;i >= 0;i--)
- putchar(aline[i]);
- putchar(4);
- fflush(stdout);
- if (ch == EOF)
- break;
- /* On a normal ^D, we won't die until after our output does. */
- }
- else if (ch == 1)
- {
- for (i = 0;i < x;i++)
- putchar(line[i]);
- for (i = y - 1;i >= 0;i--)
- putchar(aline[i]);
- fflush(stdout);
- TS; CE; FS; fflush(stderr);
- }
- else
- {
- for (i = 0;i < x;i++)
- putchar(line[i]);
- for (i = y - 1;i >= 0;i--)
- putchar(aline[i]);
- putchar('\n');
- fflush(stdout);
- }
- histpos++;
- if (histpos == HISTLEN)
- histpos = 0;
- if (histpos == minhistpos)
- {
- minhistpos++;
- if (minhistpos == HISTLEN)
- minhistpos = 0;
- }
- }
- TS; CE; FS; fflush(stderr);
- exit(0);
- }
-