
//////////////////////////////////////////////////////////////////
//////////////////////////  LINE EDITOR //////////////////////////
//////////////////////////////////////////////////////////////////

#define prn0left putch0(0x1B); putch0(0x5B); putch0(0x44);
#define prn0right putch0(0x1B); putch0(0x5B); putch0(0x43);




void line_editor(void) {
  xdata unsigned char *p1, *p2;
  unsigned char c, esc;
  unsigned char len;

  prn0(line_buf);             // print the line
  p1 = line_buf;
  while (*p1 != 0) p1++;      // init p1 to the endmark
  len = p1 - line_buf;        //  and also get the real length
  esc = 0;                    // init esc to watch escapesequences
  c = 0;
  
  while (c != 0x0D) {                 // the main init loop
    while (!(UART0INT & 0x02));        //getch0
    c = UART0BUF;                      //
                              // now the parser
    if (c == 0x0D) {                     // CR -> exit
      putch0(0x0D);
      putch0(0x0A);
    } else if (esc != 0) {                    // escape-sequence decoding
      if (esc == 0x1B) {
        esc = c;
      } else if (esc == 0x5B) {
        if ((c == 0x43) && (*p1 != 0)) {                 // 1B 5B 43 arrow right
          p1++;
          prn0right;
          esc = 0;
        } else if ((c == 0x44) && (p1 != line_buf)) {    // 1B 5B 44 arrow left
          p1--;
          prn0left;
          esc = 0;
        } else {
          esc = 0;                              // unrecognized 1b 5B xx escapesequence
        }
      } else {
        esc = 0;                                // unrecognized 1b xx xx escapesequence
      }
    } else if (c == 0x1B) {                     // ESC - escape sequence starts
      esc = c;
    } else {
      esc = 0;                         // nonESC
      if (c == 0x7F) {                 // delete
        if (*p1 != 0) {                    // treated as backspace
          p1++;
          prn0right;
        }
        c = 0x08;
      }
      if ((c == 0x08) && (len != 0)) {                 // backspace
        if (p1 != line_buf) {
          p1--;
          prn0left;
        }
        p2 = p1;
        do {
          p2++;
          c = *p2;
          p2--;
          *p2 = c;
          if (c == 0) {
            putch0(' ');
          } else {
            putch0(c);
          }
          p2++;
        } while (c != 0);
        while (p2 > p1) {
          p2--;
          prn0left;
        }
        len--;
      } else if ((c >= 0x20) && (c <= 0x7E)) {
        if (len < line_length) {       // normal characters
          p2 = p1;
          do {
            esc = *p2;
            *p2++ = c;
            putch0(c);
            c = esc;
          } while (esc != 0);               //!! trick - esc recycled for temporary storage, 
                                            //           and here implicitly gets zeroed!!!
          *p2 = c;
          p1++;
          while (p2 > p1) {
            p2--;
            prn0left;
          }
          len++;
        } else {
        putch0(0x07);                     // too much chars? -> bell
        }
      }
    }
    
  }
}

