home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / UTILITY / ED.ZIP / ED.C next >
Text File  |  1988-03-26  |  25KB  |  997 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include <stdarg.h>
  4. #include <conio.h>
  5. #include "screen.h"
  6. #include "ed.h"
  7. #define scrtop    2
  8. #define null      0
  9. #define HARDCR   20
  10. #define COLORCHAR 3
  11. #define ANSI_AA 100
  12.  
  13. struct line
  14. {
  15.  char s[160];
  16.  struct line *next;
  17.  struct line *prev;
  18. };
  19. int sx, x, y, savex, savey, scrollt, scrollb, scrwid, scrlen;
  20. int temp, totlines, curline, maxlines, curcol, console;
  21. char scrcol, abt;
  22. char temps[160];
  23. char *savfile, *tabline;
  24. char *_Cdecl strdup(char *s);
  25. int  _Cdecl toupper(int ch);
  26. struct line *l;                   /* Current working line */
  27. struct line *lastl;               /* Last line of the text */
  28. struct line *firstl;              /* First line of the text */
  29. struct line *templ;               /* Temporary line for moves and stuff */
  30.  
  31. int getkey(void)                            /* get char & scan code from kb */
  32. {
  33.  int key;
  34.  
  35.  key = getch();
  36.  return((key == 0) ? getch() + 1000 : key);
  37. }                                           /* getkey */
  38.  
  39. void scroll(int dir)
  40. {
  41.  union REGS reg;
  42.  
  43.  if (dir == UP)
  44.   reg.x.ax = 0x0601;
  45.  else
  46.   reg.x.ax = 0x0701;
  47.  reg.h.ch = (char)(scrollt - 1);
  48.  reg.h.cl = 0;
  49.  reg.h.dh = (char)(scrollb - 1);
  50.  reg.h.dl = 79;
  51.  reg.h.bh = scrcol;
  52.  int86(0x10, ®, ®);
  53. }
  54.  
  55. void beep(void)
  56. {
  57.  printf("\7");
  58. }
  59.  
  60. void fixsx(void)
  61. {
  62.  int i;
  63.  
  64.  curcol = '0';
  65.  sx = 0;
  66.  for (i = 1; i <= x; ++i)
  67.   if (l->s[i] == COLORCHAR)
  68.    curcol = l->s[++i];
  69.   else if (l->s[i] != HARDCR)
  70.    ++sx;
  71. }
  72.  
  73. void fixx(void)
  74. {
  75.  int count;
  76.  
  77.  curcol = '0';
  78.  count = 0;
  79.  x = 1;
  80.  while ((x - (count * 2)) < sx)
  81.   if (l->s[x] == COLORCHAR)
  82.    {
  83.    ++count;
  84.    curcol = l->s[++x];
  85.    ++x;
  86.    }
  87.   else
  88.    ++x;
  89. }
  90.  
  91. void sansi(char c, ...)
  92. {
  93.  va_list ap;
  94.  int i, count, param[5];
  95.  
  96.  for (count = 0; count < 5; ++count)
  97.   param[count] = 1;
  98.  va_start(ap, c);
  99.  param[0] = va_arg(ap, int);
  100.  param[1] = va_arg(ap, int);
  101.  va_end(ap);
  102.  switch(c)
  103.   {
  104.   case ANSI_AA:if (!console)
  105.                 printf("%c%c", COLORCHAR, param[0]);
  106.                break;
  107.   case ANSI_KU:--y;
  108.                if (y < scrtop)
  109.                 {
  110.                 sansi(ANSI_CS, scrtop, scrlen);
  111.                 sansi(ANSI_SF);
  112.                 sansi(ANSI_CS, 1, scrlen + 1);
  113.                 sansi(ANSI_CM, sx, y = scrtop);
  114.                 sansi(ANSI_SC);
  115.                 sansi(ANSI_CM, 1, y);
  116.                 prints("%s", l->s + 1);
  117.                 sansi(ANSI_RC);
  118.                 }
  119.                else
  120.                 printf("\033[A");
  121.                fixx();
  122.                --curline;
  123.                break;
  124.   case ANSI_KD:++y;
  125.                if (y > scrlen)
  126.                 {
  127.                 sansi(ANSI_CS, scrtop, scrlen);
  128.                 sansi(ANSI_SR);
  129.                 sansi(ANSI_CS, 1, scrlen + 1);
  130.                 sansi(ANSI_CM, sx, y = scrlen);
  131.                 sansi(ANSI_SC);
  132.                 sansi(ANSI_CM, 1, y);
  133.                 prints("%s", l->s + 1);
  134.                 sansi(ANSI_RC);
  135.                 }
  136.                else
  137.                 printf("\033[B");
  138.                fixx();
  139.                ++curline;
  140.                break;
  141.   case ANSI_KR:if (l->s[x] == COLORCHAR)
  142.                 {
  143.                 x += 2;
  144.                 curcol = l->s[x-1];
  145.                 }
  146.                else if (l->s[x] != HARDCR)
  147.                 {
  148.                 printf("\033[C");
  149.                 ++x;
  150.                 ++sx;
  151.                 }
  152.                break;
  153.   case ANSI_KL:if (l->s[x - 2] == COLORCHAR)
  154.                 {
  155.                 x -= 2;
  156.                 fixx();
  157.                 }
  158.                else
  159.                 {
  160.                 printf("\033[D");
  161.                 --sx;
  162.                 --x;
  163.                 }
  164.                break;
  165. /*7*/
  166.   case ANSI_SC:printf("\033[s");
  167.                savex = sx;
  168.                savey = y;
  169.                break;
  170. /*8*/
  171.   case ANSI_RC:printf("\033[u");
  172.                sx = savex;
  173.                y = savey;
  174.                sansi(ANSI_CM, sx, y);
  175.                break;
  176.   case ANSI_CL:sansi(ANSI_AA, curcol = '0');
  177.                printf("\033[2J\033[H");
  178.                break;
  179.   case ANSI_CE:sansi(ANSI_AA, '0');
  180.                printf("\033[K");
  181.                sansi(ANSI_AA, curcol);
  182.                break;
  183.   case ANSI_CM:printf("\033[%d;%dH", param[1], param[0]);
  184.                break;
  185. /**/
  186.   case ANSI_CS:printf("\033[%d;%dr", param[0], param[1]);
  187.                scrollt = param[0];
  188.                scrollb = param[1];
  189.                break;
  190. /**/
  191.   case ANSI_SF:scroll(DN);
  192.                printf("\033D\008 \008");
  193.                break;
  194. /**/
  195.   case ANSI_SR:printf("\033M\008 \008");
  196.                scroll(UP);
  197.                break;
  198.   case ANSI_MR:printf("\033[7m");
  199.                break;
  200.   case ANSI_ME:printf("\033[m");
  201.                break;
  202.   case ANSI_MB:printf("\033[5m");
  203.                break;
  204.   case ANSI_MD:printf("\033[1m");
  205.                break;
  206.   default:break;
  207.   }
  208. }
  209.  
  210. void status(char *s)
  211. {
  212.  sansi(ANSI_SC);
  213.  sansi(ANSI_CM, 1, scrlen + 1);
  214.  sansi(ANSI_AA, '0');
  215.  sansi(ANSI_CE);
  216.  sansi(ANSI_MR);
  217.  printf("%s", s);
  218.  sansi(ANSI_ME);
  219.  sansi(ANSI_AA, curcol);
  220.  sansi(ANSI_RC);
  221. }
  222.  
  223. int realstrlen(char *s)
  224. {
  225.  int i = -1;
  226.  
  227.  while (s[++i] != '\0');
  228.  return(i);
  229. }
  230.  
  231. int strlen(char *s)
  232. {
  233.  int i, count;
  234.  
  235.  i = -1;
  236.  count = 0;
  237.  while (s[++i] != '\0')
  238.   if (s[i] != HARDCR)
  239.    ++count;
  240.  return(count);
  241. }
  242.  
  243. int strlens(char *s)
  244. {
  245.  int i, count;
  246.  
  247.  i = -1;
  248.  count = 0;
  249.  while (s[++i] != '\0')
  250.   if (s[i] == COLORCHAR)
  251.    ++i;
  252.   else if (s[i] != HARDCR)
  253.    ++count;
  254.  return(count);
  255. }
  256.  
  257. int prints(char *msg, ...)
  258. {
  259.  va_list ap;
  260.  char output[160];
  261.  int i, ret;
  262.  
  263.  va_start(ap, msg);
  264.  ret = vsprintf(output, msg, ap);
  265.  va_end(ap);
  266. /**/
  267. sansi(ANSI_AA, curcol);
  268. /**/
  269.  i = -1;
  270.  while (output[++i] != '\0')
  271.   {
  272.   if (output[i] == COLORCHAR)
  273.    {
  274.    sansi(ANSI_AA, output[++i]);
  275.    }
  276.   else
  277.    printf("%c", output[i]);
  278.   if (output[i] == HARDCR)
  279.     putch(HARDCR);
  280.    /* This is a comment for printing out that HARDCR later... */;
  281.   }
  282.  return(ret);
  283. }
  284.  
  285. void delete(char *s, int i)
  286. {
  287.  char temp[160];
  288.  
  289.  strcpy(temp, s);
  290.  strncpy(s, temp, i);
  291.  if (temp[i] == COLORCHAR)
  292.   strcpy(s + i, temp + i + 2);
  293.  else
  294.   strcpy(s + i, temp + i + 1);
  295.  sansi(ANSI_SC);
  296.  prints("%s ", s + i);
  297.  sansi(ANSI_RC);
  298.  fixx();
  299. }
  300.  
  301. void deleteword(char *s, int i)      /* Remind me to not let it DEL HARDCR */
  302. {
  303.  char temp[160];
  304.  int start;
  305.  
  306.  strcpy(temp, s);
  307.  strncpy(s, temp, i);
  308.  start = i;
  309.  if (i < strlen(temp))
  310.   {
  311.   if (temp[i] == ' ')
  312.    {
  313.    ++i;
  314.    while ((temp[i] == ' ') && (i < strlen(temp)))
  315.     ++i;
  316.    }
  317.   else
  318.    {
  319.    if (temp[i] == COLORCHAR)
  320.     i += 2;
  321.    else
  322.     ++i;
  323.    while ((temp[i - 1] != ' ') && ((i - 1) < (strlen(temp) - 1)))
  324.     if (temp[i - 1] == COLORCHAR)
  325.      i += 2;
  326.     else
  327.      ++i;
  328.    }
  329.   }
  330.  else if (temp[i] == HARDCR)
  331.   ++i;
  332.  strcpy(s + start, temp + i);
  333.  sansi(ANSI_SC);
  334.  sansi(ANSI_CE);
  335.  prints("%s", s + start);
  336.  sansi(ANSI_RC);
  337. }
  338.  
  339. struct line *newline(void)
  340. {
  341.  struct line *t;
  342.  
  343.  t = (struct line *) malloc(sizeof(struct line));
  344.  strcpy(t->s, " ");
  345.  t->next = null;
  346.  t->prev = null;
  347.  ++totlines;
  348.  return(t);
  349. }
  350.  
  351. void nextline(void)
  352. {
  353.  if (l->next)
  354.   {
  355.   l = l->next;
  356.   sansi(ANSI_KD);
  357.   if (sx > strlens(l->s))
  358.    {
  359.    x = strlen(l->s);
  360.    sx = strlens(l->s);
  361.    sansi(ANSI_CM, sx, y);
  362.    }
  363.   }
  364. }
  365.  
  366. void prevline(void)
  367. {
  368.  if (l->prev)
  369.   {
  370.   l = l->prev;
  371.   sansi(ANSI_KU);
  372.   if (sx > strlens(l->s))
  373.    {
  374.    x = strlen(l->s);
  375.    sx = strlens(l->s);
  376.    sansi(ANSI_CM, sx, y);
  377.    }
  378.   }
  379. }
  380.  
  381. int insert(char *s, int i, int c)
  382. {
  383.  char temp[160];
  384.  
  385.  if (strlens(s) < scrwid)
  386.   {
  387.   strcpy(temp, s);
  388.   strncpy(s, temp, i - 1);
  389.   s[i] = c;
  390.   strcpy(s + i + 1, temp + i);
  391.   sansi(ANSI_SC);
  392.   prints("%s", s + i);
  393.   sansi(ANSI_RC);
  394.   return(strlen(s));
  395.   }
  396.  else if (i == strlen(s))                    /*wordwrap*/
  397.   {
  398.   templ = newline();
  399.   templ->prev = l;
  400.   templ->next = l->next;
  401.   if (l->next)
  402.    l->next->prev = templ;
  403.   l->next = templ;
  404.   if (c != ' ')
  405.    {
  406.    while (l->s[x] != ' ')
  407.     sansi(ANSI_KL);
  408.    i = l->s[strlen(l->s)];
  409.    if (curcol != '0')
  410.     {
  411.     templ->s[1] = COLORCHAR;
  412.     templ->s[2] = curcol;
  413.     strcpy(templ->s + 3, l->s + x + 1);
  414.     }
  415.    else
  416.     strcpy(templ->s + 1, l->s + x + 1);
  417.    l->s[x] = 0;
  418.    if (i != HARDCR)
  419.     templ->s[strlen(templ->s) + 1] = 0;
  420.    else
  421.     {
  422.     templ->s[strlen(templ->s) + 2] = 0;
  423.     templ->s[strlen(templ->s) + 1] = HARDCR;
  424.     }
  425.    templ->s[strlen(templ->s)] = c;
  426.    }
  427.   else
  428.    {
  429.    if (l->s[strlen(l->s)] != HARDCR)
  430.     templ->s[1] = 0;
  431.    else
  432.     {
  433.     templ->s[2] = 0;
  434.     templ->s[1] = HARDCR;
  435.     }
  436.    l->s[strlen(l->s)] = 0;
  437.    }
  438.   l = templ;
  439.   sansi(ANSI_CE);                           /*clreol                    */
  440.   if (++y == (scrlen + 1))
  441.    {
  442.    sansi(ANSI_CS, scrtop, scrlen);
  443.    sansi(ANSI_SR);
  444.    sansi(ANSI_CS, 1, scrlen + 1);
  445.    --y;
  446.    }
  447.   sansi(ANSI_CS, y, scrlen);                /*scroll region = (y,scrlen)*/
  448.   sansi(ANSI_SF);                           /*scroll down               */
  449.   sansi(ANSI_CS, 1, scrlen + 1);
  450.   sansi(ANSI_CM, 1, y);                     /*get to beginning of line  */
  451.   sansi(ANSI_CE);
  452.   prints("%s", l->s + 1);                   /*print out line            */
  453.   x = strlen(l->s);
  454.   sx = strlens(l->s);
  455.   sansi(ANSI_CM, sx, y);                    /*move to (strlen, y)       */
  456.   return(-1);
  457.   }
  458.  else
  459.   return(0);
  460. }
  461.  
  462. void redraw(void)
  463. {
  464.  int tempy;
  465.  
  466.  sansi(ANSI_CL);
  467.  scrcol = (char) *(char far *)(0xB8000001L);
  468.  sansi(ANSI_CM, 1, 1);
  469.  sansi(ANSI_AA, curcol = '0');
  470.  for (tempy = 0; tempy < (scrwid + 1); ++tempy)
  471.   printf("%c", tabline[tempy]);
  472.  templ = l;
  473.  tempy = y;
  474.  while ((y > scrtop) && templ->prev)
  475.   {
  476.   templ = templ->prev;
  477.   sansi(ANSI_KU);
  478.   }
  479.  sansi(ANSI_CM, 1, scrtop);
  480.  while ((y <= scrlen) && templ)
  481.   {
  482.   sansi(ANSI_AA, curcol = '0');
  483.   prints("%s\n", templ->s + 1);
  484.   templ = templ->next;
  485.   ++y;
  486.   }
  487.  y = tempy;
  488.  sansi(ANSI_CM, sx, y);
  489.  status("Type <Ctrl-Q><Ctrl-H> for help.");
  490. }
  491.  
  492. void load(void)
  493. {
  494.  int i;
  495.  FILE *f;
  496.  
  497.  if ((f = fopen(savfile, "r")) != NULL)
  498.   {
  499.   while (!feof(f))
  500.    if (fgets(lastl->s + 1, 160, f))
  501.     {
  502.     i = strlen(lastl->s);
  503.     if (lastl->s[i - 2] == '\001')
  504.      lastl->s[i - 2] = '\0';
  505.     else
  506.      lastl->s[i - 1] = HARDCR;
  507.     lastl->next = newline();
  508.     lastl->next->prev = lastl;
  509.     lastl = lastl->next;
  510.     }
  511.   lastl = lastl->prev;
  512.   lastl->next = null;
  513.   }
  514. }
  515.  
  516. void save(void)
  517. {
  518.  int i;
  519.  struct line *t;
  520.  FILE *f;
  521.  
  522.  if ((f = fopen(savfile, "w")) == NULL)
  523.   printf("ERROR: I couldn't open the file.\n");
  524.  else
  525.   {
  526.   t = firstl;
  527.   while (t != null)
  528.    {
  529.    if (t->s[strlen(t->s)] == HARDCR)
  530.     {
  531.     for (i = 1; i < strlen(t->s); ++i)
  532.      fprintf(f, "%c", t->s[i]);
  533.     fprintf(f, "\n");
  534.     }
  535.    else if (t->next == null)
  536.     fprintf(f, "%s\n", t->s + 1);
  537.    else
  538.     fprintf(f, "%s\001\n", t->s + 1);
  539.    t = t->next;
  540.    }
  541.   }
  542. }
  543.  
  544. main(int argc, char *argv[])
  545. {
  546.  int c;
  547.  
  548.  savfile = null;
  549.  maxlines = 60;
  550.  scrwid = 79;
  551.  scrlen = 24;
  552.  console = 0;
  553.  if ((argc > 1) && (argv[1][0] != '-'))
  554.   savfile = strdup(argv[1]);
  555.  for (c = 1; c < argc; ++c)
  556.   if (argv[c][0] == '-')
  557.    switch(toupper(argv[c][1]))
  558.     {
  559.     case 'L':maxlines = (int) strtol(argv[c] + 2, NULL, 0);
  560.              break;
  561.     case 'C':scrwid = (int) strtol(argv[c] + 2, NULL, 0) - 1;
  562.              break;
  563.     case 'H':scrlen = (int) strtol(argv[c] + 2, NULL, 0) - 1;
  564.              break;
  565.     case 'A':console = 1;
  566.              break;
  567.     }
  568.  abt = 0;
  569.  totlines = 0;
  570.  curcol = '0';
  571.  curline = 1;
  572.  firstl = lastl = l = newline();
  573.  sx = x = 1;
  574.  y = scrtop;
  575.  tabline = strdup("|----+----+----+----+----+----+----+----|----+----+----+----+----+----+----+---|");
  576.  load();
  577.  redraw();
  578.  while (!abt && ((c = getkey()) != 26))     /* <Ctrl-Z> = End of file */
  579.   {
  580.   switch(c)
  581.    {
  582.    case 8:                              /* <Ctrl-H> = Backspace */
  583.    case 127:                            /* <Ctrl-Backspace> = Delete */
  584.     if (x > 1)
  585.      {
  586.      sansi(ANSI_KL);
  587.      delete(l->s, x);
  588.      }
  589.     break;
  590.    case 14:                             /* <Ctrl-N> = insert line */
  591.    case 13:                             /* <Ctrl-M> or <CR> */
  592.     if (totlines < maxlines)
  593.      {
  594.      templ = newline();
  595.      templ->prev = l;
  596.      templ->next = l->next;
  597.      if (l->next)
  598.       l->next->prev = templ;
  599.      l->next = templ;
  600.      strcpy(templ->s + 1, l->s + x);
  601.      l->s[x] = HARDCR;
  602.      l->s[x + 1] = 0;
  603.      prints("%s", l->s + x);
  604.      l = templ;
  605.      sansi(ANSI_CE);                           /*clreol                    */
  606.      if (++y == (scrlen + 1))
  607.       {
  608.       sansi(ANSI_CS, scrtop, scrlen);
  609.       sansi(ANSI_SR);
  610.       sansi(ANSI_CS, 1, scrlen + 1);
  611.       --y;
  612.       }
  613.      sansi(ANSI_CM, sx = x = 1, y);            /*gotoxy(1, y) if CR        */
  614.      sansi(ANSI_SC);                           /*save cursor               */
  615.      sansi(ANSI_CS, y, scrlen);                /*scroll region = (y,scrlen)*/
  616.      sansi(ANSI_SF);                           /*scroll down               */
  617.      sansi(ANSI_CS, 1, scrlen + 1);
  618.      sansi(ANSI_CE);
  619.      prints("%s", l->s + 1);                   /*print out line            */
  620.      sansi(ANSI_RC);                           /*restore cursor            */
  621.      if (c == 14)
  622.       {
  623.       l = l->prev;
  624.       sx = strlens(l->s);
  625.       x = strlen(l->s);
  626.       sansi(ANSI_CM, sx, --y);
  627.       }
  628.      }
  629.     break;
  630.    case 10:                /* <Ctrl-J> = Delete to EOL */
  631.     l->s[x] = 0;
  632.     sansi(ANSI_CE);
  633.     break;
  634.    case 25:                             /* <Ctrl-Y> = Delete Line */
  635.     if (l->next)
  636.      {
  637.      if (l->prev)
  638.       l->prev->next = l->next;
  639.      l->next->prev = l->prev;
  640.      templ = l;
  641.      l = l->next;
  642.      free(templ);
  643.      sansi(ANSI_CM, sx = x = 1, y);
  644.      sansi(ANSI_SC);
  645.      sansi(ANSI_CS, y, scrlen);
  646.      sansi(ANSI_SR);
  647.      sansi(ANSI_CS, 1, scrlen + 1);
  648.      sansi(ANSI_RC);
  649.      --totlines;
  650.      templ = l;
  651.      temp = y;
  652.      while ((temp < scrlen) && (templ->next))
  653.       {
  654.       templ = templ->next;
  655.       ++temp;
  656.       }
  657.      if (temp == scrlen)
  658.       {
  659.       sansi(ANSI_SC);
  660.       sansi(ANSI_CM, 1, scrlen);
  661.       prints("%s", templ->s + 1);
  662.       sansi(ANSI_RC);
  663.       }
  664.      }
  665.     else if (l->prev)
  666.      {
  667.      l = l->prev;
  668.      free(l->next);
  669.      l->next = null;
  670.      sansi(ANSI_CM, sx = x = 1, y);
  671.      sansi(ANSI_CE);
  672.      sansi(ANSI_KU);
  673.      --totlines;
  674.      }
  675.     else if (strlen(l->s) > 1)
  676.      {
  677.      strcpy(l->s, " ");
  678.      sansi(ANSI_CM, sx = x = 1, y);
  679.      sansi(ANSI_CE);
  680.      }
  681.     else
  682.      beep();
  683.     break;
  684.    case 7:                              /* <Ctrl-G> = Delete character */
  685.    case DEL:
  686.     if ((x < strlen(l->s)) || (l->s[x] == HARDCR))
  687.      delete(l->s, x);
  688.     break;
  689.    case 24:                             /* <Ctrl-X> = Cursor down */
  690.    case CRSRDN:
  691.     nextline();
  692.     break;
  693.    case 5:                              /* <Ctrl-E> = Cursor up */
  694.    case CRSRUP:
  695.     prevline();
  696.     break;
  697.    case 4:                              /* <Ctrl-D> = Cursor right */
  698.    case CRSRRGT:
  699.     if (x < strlen(l->s))
  700.      sansi(ANSI_KR);
  701.     break;
  702.    case 19:                             /* <Ctrl-S> = Cursor left */
  703.    case CRSRLFT:
  704.     if (x > 1)
  705.      sansi(ANSI_KL);
  706.     break;
  707.    case 1:                              /* <Ctrl-A> = Word left */
  708.    case CTRLCRSRLFT:
  709.     if (x > 1)
  710.      {
  711.      while ((l->s[x - 1] == ' ') && (x > 1))
  712.       sansi(ANSI_KL);
  713.      while ((l->s[x - 1] != ' ') && (x > 1))
  714.       sansi(ANSI_KL);
  715.      }
  716.     else if (l->prev)
  717.      {
  718.      l = l->prev;
  719.      x = strlen(l->s);
  720.      sx = strlens(l->s);
  721.      sansi(ANSI_KU);
  722.      sansi(ANSI_CM, sx, y);
  723.      }
  724.     break;
  725.    case 6:                              /* <Ctrl-F> = Word right */
  726.    case CTRLCRSRRGT:
  727.     if ((x < strlen(l->s)) && (l->s[x] != HARDCR))
  728.      {
  729.      if ((l->s[x] == ' ') && (x < strlen(l->s)))
  730.       while ((l->s[x] == ' ') && (x < strlen(l->s)))
  731.        sansi(ANSI_KR);
  732.      else
  733.       {
  734.       while ((l->s[x - 1] == ' ') && (x < strlen(l->s)))
  735.        sansi(ANSI_KR);
  736.       while ((l->s[x - 1] != ' ') && (x < strlen(l->s)))
  737.        sansi(ANSI_KR);
  738.       while ((l->s[x] == ' ') && (x < strlen(l->s)))
  739.        sansi(ANSI_KR);
  740.       }
  741.      }
  742.     else if (l->next)
  743.      {
  744.      l = l->next;
  745.      sansi(ANSI_KD);
  746.      sansi(ANSI_CM, sx = x = 1, y);
  747.      }
  748.     break;
  749.    case 20:                             /* <Ctrl-T> = Delete next word */
  750.     deleteword(l->s, x);
  751.     break;
  752.    case 23:                /* <Ctrl-W> = Delete prev word */
  753.     if (x > 1)
  754.      {
  755.      while ((l->s[x - 1] == ' ') && (x > 1))
  756.       sansi(ANSI_KL);
  757.      while ((l->s[x - 1] != ' ') && (x > 1))
  758.       sansi(ANSI_KL);
  759.      }
  760.     else if (l->prev)
  761.      {
  762.      l = l->prev;
  763.      x = strlen(l->s);
  764.      sx = strlens(l->s);
  765.      sansi(ANSI_KU);
  766.      sansi(ANSI_CM, sx, y);
  767.      }
  768.     deleteword(l->s, x);
  769.     break;
  770.    case 9:                              /* <Ctrl-I> = Tab */
  771.     if ((6 - (sx % 5)) <= (scrwid - sx))
  772.      {
  773.      insert(l->s, x, ' ');
  774.      sansi(ANSI_KR);
  775.      while (sx % 5 != 1)
  776.       {
  777.       insert(l->s, x, ' ');
  778.       sansi(ANSI_KR);
  779.       }
  780.      }
  781.     break;
  782.    case 12:                             /* <Ctrl-L> = Redraw screen */
  783.     redraw();
  784.     break;
  785.    case 16:                             /* <Ctrl-P> = Change color */
  786.     status("Enter a number (0-8)");
  787.     c = getkey();
  788.     status("");
  789.     if ((c >= '0') && (c <= '7'))
  790.      {
  791.      strcpy(temps, l->s);
  792.      strncpy(l->s, temps, x - 1);
  793.      l->s[x] = COLORCHAR;
  794.      l->s[x + 1] = c;
  795.      strcpy(l->s + x + 2, temps + x);
  796.      curcol = c;
  797.      sansi(ANSI_SC);
  798.      prints("%s", l->s + x);
  799.      sansi(ANSI_RC);
  800.      x += 2;
  801.      }
  802.     break;
  803.    case 11:                /* <Ctrl-K> = Secondary commands */
  804.     if (c == 11)
  805.      {
  806.      status("Enter secondary code");
  807.      c = getkey();
  808.      status("");
  809.      }
  810.     switch(c)
  811.      {
  812.      case   4:                          /* <Ctrl-D> = Exit editor */
  813.      case  68:                          /* 'D'                    */
  814.      case 100:                          /* 'd'                    */
  815.       abt = 2;                          /* abort but save */
  816.       break;
  817.      }
  818.     break;
  819.    case 17:                             /* <Ctrl-Q> = Secondary commands */
  820.    case HOME:
  821.    case END:
  822.    case CTRLPGUP:
  823.    case CTRLPGDN:
  824.    case CTRLHOME:
  825.    case CTRLEND:
  826.     if (c == 17)
  827.      {
  828.      status("Enter secondary code");
  829.      c = getkey();
  830.      status("");
  831.      }
  832.     switch(c)
  833.      {
  834.      case   8:                            /* <Ctrl-H> = help */
  835.      case  72:                            /* 'H'             */
  836.      case 104:                            /* 'h'             */
  837.       sansi(ANSI_CL);
  838.       printf("|               Movement                 |         Insert and Delete          |\n");
  839.       printf("|----------------------------------------|------------------------------------|\n");
  840.       printf("|Ctrl-E = cursor up   \\                  | Ctrl-G = delete char at cursor     |\n");
  841.       printf("|Ctrl-X = cursor down  |         E       | Ctrl-H = delete char behind cursor |\n");
  842.       printf("|Ctrl-S = cursor left   >   A  S   D  F  | Ctrl-T = delete the next word      |\n");
  843.       printf("|Ctrl-D = cursor right |         X       | Ctrl-W = delete the previous word  |\n");
  844.       printf("|Ctrl-A = word left    |                 | Ctrl-J = delete to end of the line |\n");
  845.       printf("|Ctrl-F = word right  /                  | Ctrl-Y = delete a line             |\n");
  846.       printf("|Ctrl-Q +                                | Ctrl-N = insert a line at cursor   |\n");
  847.       printf("|   Ctrl-E = top of screen               | Ctrl-I = insert a tab              |\n");
  848.       printf("|   Ctrl-X = bottom of screen            |====================================|\n");
  849.       printf("|   Ctrl-S = first char of line          |            Miscellaneous           |\n");
  850.       printf("|   Ctrl-D = last char of line           |------------------------------------|\n");
  851.       printf("|   Ctrl-R = top of message              | Ctrl-L = redraw the screen         |\n");
  852.       printf("|   Ctrl-C = end of message              | Ctrl-P +                           |\n");
  853.       printf("|                                        |    digit = change the color        |\n");
  854.       printf("|=============================================================================|\n");
  855.       printf("                         |       Ending the message       |                    \n");
  856.       printf("                         |--------------------------------|                    \n");
  857.       printf("                         | Ctrl-Z = exit and save message |                    \n");
  858.       printf("                         | Ctrl-Q +                       |                    \n");
  859.       printf("                         |    Ctrl-Z = abort message      |                    \n");
  860.       printf("                         |================================|                    \n");
  861.       status("Press any key to continue");
  862.       getkey();
  863.       status("");
  864.       redraw();
  865.       break;
  866.      case 5:                              /* <Ctrl-E> = top of screen */
  867.      case 69:                             /* 'E'                      */
  868.      case 101:                            /* 'e'                      */
  869.      case HOME:
  870.       while ((y > scrtop) && (l->prev))
  871.        {
  872.        l = l->prev;
  873.        sansi(ANSI_KU);
  874.        }
  875.       if (sx > strlens(l->s))
  876.        {
  877.        x = strlen(l->s);
  878.        sx = strlens(l->s);
  879.        }
  880.       sansi(ANSI_CM, sx, y);
  881.       break;
  882.      case 24:                             /* <Ctrl-X> = bottom of screen */
  883.      case 88:                             /* 'X'                         */
  884.      case 120:                            /* 'x'                         */
  885.      case END:
  886.       while ((y < scrlen) && (l->next))
  887.        {
  888.        l = l->next;
  889.        sansi(ANSI_KD);
  890.        }
  891.       if (sx > strlens(l->s))
  892.        {
  893.        x = strlen(l->s);
  894.        sx = strlens(l->s);
  895.        }
  896.       sansi(ANSI_CM, sx, y);
  897.       break;
  898.      case 19:                             /* <Ctrl-S> = beginning of line */
  899.      case 83:                             /* 'S'                          */
  900.      case 115:                            /* 's'                          */
  901.      case CTRLPGUP:
  902.       sansi(ANSI_CM, sx = x = 1, y);
  903.       break;
  904.      case 4:                              /* <Ctrl-D> = end of line */
  905.      case 68:                             /* 'D'                    */
  906.      case 100:                            /* 'd'                    */
  907.      case CTRLPGDN:
  908.       x = strlen(l->s);
  909.       sx = strlens(l->s);
  910.       sansi(ANSI_CM, sx, y);
  911.       break;
  912.      case 18:                             /* <Ctrl-R> = top of file */
  913.      case 82:                             /* 'R'                    */
  914.      case 114:                            /* 'r'                    */
  915.      case CTRLHOME:
  916.       while (l != firstl)
  917.        {
  918.        l = l->prev;
  919.        sansi(ANSI_KU);
  920.        }
  921.       sansi(ANSI_CM, sx = 1, y);
  922.       break;
  923.      case 3:                              /* <Ctrl-C> = bottom of file */
  924.      case 67:                             /* 'C'                       */
  925.      case 99:                             /* 'c'                       */
  926.      case CTRLEND:
  927.       while (l != lastl)
  928.        {
  929.        l = l->next;
  930.        sansi(ANSI_KD);
  931.        }
  932.       x = strlen(l->s);
  933.       sx = strlens(l->s);
  934.       sansi(ANSI_CM, sx, y);
  935.       break;
  936.      case 26:                             /* <Ctrl-Z> = abort message */
  937.      case 90:                             /* 'Z'                      */
  938.      case 122:                            /* 'z'                      */
  939.       status("Abort: Are you sure?");
  940.       sansi(ANSI_SC);
  941.       sansi(ANSI_CM, 22, scrlen + 1);
  942.       while (((c = getkey()) != 'y') && (c != 'Y') && (c != 'n') && (c != 'N'));
  943.       sansi(ANSI_RC);
  944.       status("");
  945.       if ((c == 'y') || (c == 'Y'))
  946.        abt = 1;
  947.       break;
  948.      }
  949.     break;
  950.    default:
  951.     if ((c >= 32) && (c <= 255))
  952.      if ((strlens(l->s) < scrwid) && (x == realstrlen(l->s)))
  953.       {
  954.       strcpy(temps, l->s);
  955.       strncpy(l->s, temps, x - 1);
  956.       l->s[x] = c;
  957.       strcpy(l->s + x + 1, temps + x);
  958.       prints("%c", c);
  959.       ++x;
  960.       ++sx;
  961.       }
  962.      else
  963.       switch(insert(l->s, x, c))
  964.        {
  965.        case -1:break;
  966.        case  0:status("\7Too many characters in the line.");
  967.                break;
  968.        default:sansi(ANSI_KR);
  969.                break;
  970.        }
  971.     break;
  972.    }
  973.   if (l->next == null)
  974.    lastl = l;
  975.   }
  976.  sansi(ANSI_CM, 1, scrlen + 1);
  977.  sansi(ANSI_CE);
  978.  if (abt != 1)
  979.   {
  980.   if (savfile != null)
  981.    {
  982.    printf("Saving %d lines\n", totlines);
  983.    save();
  984.    exit(0);
  985.    }
  986.   else
  987.    {
  988.    printf("I didn't get a filename to save it under!\n");
  989.    exit(2);
  990.    }
  991.   }
  992.  else
  993.   {
  994.   printf("Aborted\n");
  995.   exit(1);
  996.   }
  997. }