'===========================================================================
' Subject: INCOMPLETE EDITOR                  Date: 05-11-96 (04:26)       
'  Author: Bob Kohl                           Code: QB, QBasic, PDS        
'  Origin: FidoNet QUIK_BAS Echo            Packet: DEMOS.ABC
'===========================================================================
'   Here is something I tossed together. It's been posted in the Basic
'   newsgroups and it always looked interesting, so I tried to modify it. This
'   is the result. It's not perfect, but it has potential.

DEFINT A-Z
DECLARE SUB Editor (Text$, Leftcol, RightCol, KeyCode)

COLOR 9: CLS : LOCATE 1, 1: COLOR 4, 7
PRINT "  π   F       E       S         R      C         O         W             H    "
LOCATE 1, 8: COLOR 0, 7: PRINT "ile": LOCATE 1, 16: PRINT "dit"
LOCATE 1, 24: PRINT "earch": LOCATE 1, 34: PRINT "un": LOCATE 1, 41
PRINT "ompile": LOCATE 1, 51: PRINT "ption": LOCATE 1, 61: PRINT "indow"
LOCATE 1, 75: PRINT "elp   "
COLOR 11, 1
PRINT "ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»"
LOCATE 3, 1: PRINT "Ί"
FOR I = 4 TO 20
    LOCATE I, 1  'GotoXY(1,I);
    PRINT "Ί"
NEXT I
COLOR 0, 7: LOCATE 3, 80: PRINT ""
COLOR 11, 1: LOCATE 21, 1: PRINT "Ί"
COLOR 0, 7: LOCATE 21, 80: PRINT "": COLOR 11, 1
LOCATE 22, 1
PRINT "ΘΝΝΝΝ[       ]ΝΝΝ": LOCATE 22, 18
COLOR 0, 7: PRINT "": LOCATE 22, 19
COLOR 8, 7: PRINT "²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²"
COLOR 0, 7: LOCATE 22, 78: PRINT        '*** use CHR$(26) with the print
COLOR 11, 1: LOCATE 22, 79: PRINT "ΔΩ"
COLOR 8, 7
FOR k = 4 TO 20
    LOCATE k, 80: PRINT "²"
NEXT k
COLOR 9, 11
FOR J = 1 TO 80
    LOCATE 23, J: PRINT "²"
NEXT J
COLOR 4, 0
LOCATE 23, 20: PRINT " Bob's Editor "; : LOCATE 23, 36: COLOR 12, 0
COLOR 15, 9
' New Program Name " BKEDFIDO.BAS "
'==============================================================
'EDITIT.BAS the stub of a simple text editor modifed from the
'EDITOR.BAS line editor example of Ethan Winer in "PC Magazines
'BASIC tips and Utilities. This example reads a given line into
'an array, passes that to the edit subprogram. There is primitive
'line wrapping, and simple scrolling, but I haven't included
'page up or page down. The editor starts in overtype mode and is
'toggled with the insert key.

DIM FullLine$(1 TO 1000)    'Make an array for holding text
DIM D$(8)

MaxCols = 79
MaxRows = 23   '43    'or 25 for more readable text
RowNo = 3                               'Initialize Variables
LineNo = 1
LineUp = 0
MaxLine = 1

Text$ = FullLine$(1)           'Initialize the input routine
Leftcol = 2                    'set the left column
RightCol = 79                   'and the right column

DO
   LOCATE RowNo, Leftcol
  
   DO                           'Now call the edit routine
   CALL Editor(Text$, Leftcol, RightCol, KeyCode)
   LOOP UNTIL KeyCode           'Wait for a key that is returned by the editor
   FullLine$(LineNo) = Text$    'Assign new text to the array
  
   SELECT CASE KeyCode
        CASE -16, 27          ' ALT+Q or Escape
                OPEN "temp.txt" FOR OUTPUT AS #1
                FOR T = 1 TO LineNo
                    PRINT #1, Text$
                NEXT T
                CLOSE #1    ' temp.txt file closed
                LOCATE RowNo, LineNo + 2
                PRINT "  Save File As (Only 8 Chararacter please)   ";
                INPUT T$
                T$ = T$ + ".txt": temp$ = "temp.txt"
                LOCATE RowNo + 1, LineNo + 2
                PRINT T$: SLEEP 5
                NAME temp$ AS T$
                EXIT DO
        CASE 13               'Enter Key
                LineNo = LineNo + 1
                RowNo = RowNo + 1
                MaxLine = LineNo
                IF RowNo > (MaxRows - 2) THEN           'Complex proceedure for scrolling up
                        LineUp = LineUp + 1             'a line if more es than on monitor
                        StartRow = 3
                        RowNo = (MaxRows - 2)
                        FOR I = 1 TO (MaxRows - 4)
                                LOCATE StartRow, Leftcol
                                PRINT SPACE$(78)
                                LOCATE StartRow, Leftcol
                                PRINT FullLine$(I + LineUp)
                                StartRow = StartRow + 1
                        NEXT
                END IF

                Text$ = FullLine$(LineNo)
       
        CASE -72                    'Up Arrow
                RowNo = RowNo - 1
                LineNo = LineNo - 1
                IF RowNo < 3 THEN
                        RowNo = 3
                        IF LineUp > 0 THEN       'Scroll Up
                                StartRow = 3
                                LineUp = LineUp - 1
                                FOR I = 1 TO (MaxRows - 4)
                                        LOCATE StartRow, Leftcol
                                        PRINT SPACE$(76);   '****** FIXED
                                        LOCATE StartRow, Leftcol
                                        PRINT FullLine$(I + LineUp);
                                        StartRow = StartRow + 1
                                NEXT
                        END IF
                END IF
                IF LineNo < 1 THEN LineNo = 1
                Text$ = FullLine$(LineNo)
       
        CASE -80                       'Down Arrow
                LineNo = LineNo + 1
                IF LineNo > MaxLine THEN
                        LineNo = MaxLine
                        RowNo = RowNo
                ELSE
                        RowNo = RowNo + 1
                END IF
               
                IF RowNo > (MaxRows - 2) THEN              'Scroll Down
                        LineUp = LineUp + 1
                        StartRow = 3
                        RowNo = (MaxRows - 2)
                                FOR I = 1 TO (MaxRows - 4)
                                        LOCATE StartRow, Leftcol
                                        PRINT SPACE$(78);
                                        LOCATE StartRow, Leftcol
                                        PRINT FullLine$(I + LineUp);
                                        StartRow = StartRow + 1
                                NEXT
                END IF
                Text$ = FullLine$(LineNo)
   END SELECT

LOOP

'cls
'LOCATE 1, 1
'FOR i = 1 TO LineNo
'PRINT FullLine$(i)
'NEXT

END

SUB Editor (Text$, Leftcol, RightCol, KeyCode)

  '----- Find the cursor's size.
  DEF SEG = 0
  IF PEEK(&H463) = &HB4 THEN
     CsrSize = 12               'mono uses 13 scan lines
  ELSE
     CsrSize = 12                'color uses 8
  END IF

  '----- Work with a temporary copy.
  Edit$ = SPACE$(RightCol - Leftcol + 1)
  LSET Edit$ = Text$

  '----- See where to begin editing and print the string.
  TxtPos = POS(0) - Leftcol + 1
  IF TxtPos < 1 THEN TxtPos = 1
  IF TxtPos > LEN(Edit$) THEN TxtPos = LEN(Edit$)

  LOCATE , Leftcol
  PRINT Edit$;

  '----- This is the main loop for handling key presses.
  DO
     LOCATE , Leftcol + TxtPos - 1, 1

     DO
       Ky$ = INKEY$
     LOOP UNTIL LEN(Ky$)        'wait for a keypress

     IF LEN(Ky$) = 1 THEN       'create a key code
       KeyCode = ASC(Ky$)       'regular character key
     ELSE                       'extended key
       KeyCode = -ASC(RIGHT$(Ky$, 1))
     END IF

     '----- Branch according to the key pressed.
     SELECT CASE KeyCode
       '----- Backspace: decrement the pointer and the
       '      cursor, and ignore if in the first column.
       CASE 8
         TxtPos = TxtPos - 1
         LOCATE , Leftcol + TxtPos - 1, 0
         IF TxtPos > 0 THEN
           IF InsStatus THEN
             MID$(Edit$, TxtPos) = MID$(Edit$, TxtPos + 1) + " "
           ELSE
             MID$(Edit$, TxtPos) = " "
           END IF
           PRINT MID$(Edit$, TxtPos);
         END IF

       '----- Enter or Escape: this block is optional in
       '      case you want to handle these separately.
       CASE 13, 27, -16
         EXIT DO                'exit the subprogram

       '----- Letter keys: turn off the cursor to hide
       '      the printing, handle Insert mode as needed.
       CASE 32 TO 254
         LOCATE , , 0
         IF InsStatus THEN      'expand the string
           MID$(Edit$, TxtPos) = Ky$ + MID$(Edit$, TxtPos)
           PRINT MID$(Edit$, TxtPos);
         ELSE                   'else insert character
           MID$(Edit$, TxtPos) = Ky$
           PRINT Ky$;
         END IF
         TxtPos = TxtPos + 1    'update position counter
         IF TxtPos = LEN(Edit$) THEN
                KeyCode = 13
                EXIT DO
         END IF
       '----- Left arrow: decrement the position counter.
       CASE -75
         TxtPos = TxtPos - 1
       '----- Right arrow: increment position counter.
       CASE -77
         TxtPos = TxtPos + 1

       '----- Home: jump to the first character position.
       CASE -71
         TxtPos = 1

       '----- End: search for the last non-blank, and
       '      make that the current editing position.
       CASE -79
         FOR N = LEN(Edit$) TO 1 STEP -1
           IF MID$(Edit$, N, 1) <> " " THEN EXIT FOR
         NEXT
         TxtPos = N + 1
         IF TxtPos > LEN(Edit$) THEN TxtPos = LEN(Edit$)

       '----- Insert key: toggle the Insert state and
       '      adjust the cursor size.
       CASE -82
         InsStatus = NOT InsStatus
         IF InsStatus THEN
           LOCATE , , , CsrSize \ 2, CsrSize
         ELSE
           LOCATE , , , CsrSize - 1, CsrSize
         END IF

       '----- Delete: delete the current character and
       '      reprint what remains in the string.
       CASE -83
         MID$(Edit$, TxtPos) = MID$(Edit$, TxtPos + 1) + " "
         LOCATE , , 0
         PRINT MID$(Edit$, TxtPos);

       '---- All other keys: exit the subprogram
       CASE ELSE
         EXIT DO
     END SELECT

  '----- Loop until the cursor moves out of the field.
  LOOP UNTIL TxtPos < 1 OR TxtPos > LEN(Edit$)

  Edit$ = LTRIM$(RTRIM$(Edit$))         'trim the text
  Text$ = Edit$
END SUB

