home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / basic / library / qb_pds / edit / myed.bas next >
Encoding:
BASIC Source File  |  1988-05-29  |  40.3 KB  |  1,392 lines

  1. ''''''''''''''''''''''''''''''''''''MyEd''''''''''''''''''''''''''''''''''''
  2.  
  3. 'MyEd is a text editor written in MicroSoft's QuickBasic.
  4. 'It has been made as modular as possible so that you can very easily
  5. 'customize it to create a stand-alone word processor or incorporate it
  6. 'into your own program that might need editing capabilities.  Naturally,
  7. 'a knowledge of BASIC is required, as is a BASIC compiler.
  8.  
  9. 'A LIMITED LICENSE is hereby granted to individuals, schools and other non-
  10. 'profit entities to use all or part of the code in this program file for
  11. 'their own private use so long as proper credit and the following information
  12. 'is included in your source code:
  13.  
  14. 'COMMERCIAL USE...
  15. 'of all or part of this code, including use within a business, or
  16. 'ANY DISTRIBUTION of all or part of this code is allowed BY LICENSE ONLY.
  17. 'Unlicensed distribution or use of this code is a violation of copyright law
  18. 'and subject to civil and criminal prosecution, including substantial fines.
  19. '
  20. '
  21. 'This file has been heavily annotated and long, descriptive names used for
  22. 'variables. Beyond this, we cannot provide support for people using this code
  23. 'under the free Limited License (see prior screen).  If you wish to register
  24. 'for telephone support, send $50 to the address above.  If you are new to
  25. 'QuickBASIC, you can order a QB Tutorial on disk for $9 from the same author.
  26.  
  27. 'This program uses CALL ABSOLUTE, which requires you to set up and use
  28. 'the file USERLIB.EXE. If you do not know how, please read your QB manual
  29. 'or call MicroSoft.  USERLIB comes with QB.
  30.  
  31. 'Load this program into QB as follows:  QB MYED /L USERLIB.EXE
  32.  
  33. 'The program can be used with StayRes from MicroHelp. This add-on will allow
  34. 'you to make the program resident.  MicroHelp's phone number is 404-973-9272.
  35.  
  36. 'Programmers who submit significant enhancements to this code or who write
  37. 'public domain or shareware programs may be eligible for a free license to
  38. 'use this code.  We are going to continue adding features to this code.  
  39. 'Updates will be made available. 
  40.  
  41. DEFINT A-Z
  42.  
  43. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  44. ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '
  45. ' 'This section of parameters should be modified to define the' '
  46. ' 'size and location of the edit area you wish to have:       ' '
  47.             First.Col =  1                            ' '
  48.             Last.Col  = 80                            ' '
  49.             First.Row =  1                            ' '
  50.             Last.Row  = 24                            ' '
  51.             Msg.Line  = 25                            ' '
  52.             Max.Lines =500                            ' '
  53.             DIM Text$(500), Text.Len(500)             ' '
  54. ' 'Dimension Text$ and Text.Len to the maximum number of lines' '
  55. ' 'Our testing indicates that a maximum of about 500 lines is ' '
  56. ' 'possible given BASIC's 64k data segment.                   ' '
  57. ' '                                                           ' '
  58. ' 'There are a couple of places where row and column numbers  ' '
  59. ' 'are hard-coded in.  To find these, search for LOCATE.      ' '
  60. ' '                                                           ' '
  61. ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '
  62. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  63. '============================================================================
  64. 10'                         MAIN PROGRAM LOOP
  65.  
  66. DIM Locks$(3), On.Off$(1), QPrint.CODE(127), Change$(10)
  67. ON ERROR GOTO Err.Trap
  68. GOSUB Initialize.Parameters
  69. GOSUB Load.File
  70. WHILE NOT the.end.of.the.universe  'loop for a long time
  71.   LOCATE Msg.Line,6,0: PRINT Line.Num;
  72.   LOCATE Msg.Line,16 : PRINT Char.Num;   'position cursor:
  73.   LOCATE First.Row+Line.Num-First.View.Line+1, First.Col+Char.Num-1,1
  74.   W$=""
  75.   WHILE W$=""
  76.     W$=INKEY$ : GOSUB Check.Lock.Status
  77.   WEND
  78.   IF LEN(W$) = 1_
  79.     THEN GOSUB Normal.key.pressed_
  80.     ELSE GOSUB Special.key.pressed
  81.   IF KY=Alt.X OR W$=Esc$ THEN GOSUB Save.Exit
  82. WEND
  83.  
  84. '============================================================================
  85. '                       Main program loop routines:
  86.  
  87. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  88.  Check.Lock.Status:
  89. 110'==============
  90. DEF SEG=&H40: New.Status=PEEK(&H17) AND 96: DEF SEG
  91. IF Lock.Status <> New.Status THEN
  92.   Addr=VARPTR(QPrint.CODE(0))
  93.   x$=Locks$(New.Status/32)
  94.   r110=25: c110=73
  95.   CALL ABSOLUTE(x$, r110, c110, Attrib, Addr)
  96.   Lock.Status = New.Status
  97.   IF Lock.Tone > 0 THEN SOUND Lock.Tone+New.Status, Duration!
  98. END IF
  99. RETURN
  100. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  101.  Normal.key.pressed:
  102. 120'===============
  103. IF W$=>" " THEN GOSUB AlphaNumeric.Key.Pressed_
  104.       ELSE IF W$=Entr$ THEN GOSUB Enter.Pressed_
  105.       ELSE IF W$=Bksp$ THEN GOSUB Backspace.Pressed
  106. RETURN
  107. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  108.  
  109.  Special.key.pressed:   'INKEY$ scan code = 2 characters
  110. 130'================
  111. KY= ASC(RIGHT$(W$,1))
  112. 'cursor keys:
  113. IF KY=RT.Cursor THEN GOSUB Cursor.Right     ELSE_
  114. IF KY=LF.Cursor THEN GOSUB Cursor.Left      ELSE_
  115. IF KY=UP.Cursor THEN GOSUB Cursor.Up        ELSE_
  116. IF KY=DN.Cursor THEN GOSUB Cursor.Dn        ELSE_
  117. IF KY=Pg.Up     THEN GOSUB Page.Up          ELSE_
  118. IF KY=Pg.Dn     THEN GOSUB Page.Dn          ELSE_
  119. IF KY=Home      THEN GOSUB Move.Home        ELSE_
  120. IF KY=End.Key   THEN GOSUB Move.to.End      ELSE_
  121. IF KY=Del.Key   THEN GOSUB Del.Char         ELSE_
  122. IF KY=Ins.Key   THEN GOSUB Toggle.Insert    ELSE_
  123. IF KY=Ctrl.RT   THEN GOSUB Go.To.Next.Word  ELSE_
  124. IF KY=Ctrl.LF   THEN GOSUB Go.To.Prev.Word  ELSE_
  125. IF KY=Ctrl.End  THEN GOSUB Del.to.EOL       ELSE_
  126. IF KY=Ctrl.PgUp THEN GOSUB Go.To.File.Bgn   ELSE_
  127. IF KY=Ctrl.PgDn THEN GOSUB Go.To.File.End   ELSE_
  128. _' special functions:
  129. IF KY=Alt.B THEN GOSUB Define.Block     ELSE_
  130. IF KY=Alt.E THEN GOSUB Erase.Block      ELSE_
  131. IF KY=Alt.P THEN GOSUB Paste.Block      ELSE_
  132. IF KY=Alt.U THEN GOSUB Unmark.Block     ELSE_
  133. IF KY=Alt.D THEN GOSUB Del.Line         ELSE_
  134. IF KY=Alt.R THEN GOSUB Reform           ELSE_
  135. IF KY=Alt.I THEN GOSUB Toggle.Indent    ELSE_
  136. IF KY=Alt.W THEN Wrap.On = Not Wrap.On  ELSE_
  137. IF KY=Alt.F THEN GOSUB Find.Text        ELSE_
  138. IF KY=Alt.C THEN GOSUB Clear.Lines      ELSE_
  139. IF KY=Alt.N THEN GOSUB New.File         ELSE_
  140. IF KY=Alt.M THEN GOSUB Set.Rt.Margin    ELSE_
  141. IF KY=Alt.H THEN GOSUB Help.Screen      ELSE_
  142. IF KY=Alt.G THEN GOSUB Get.more.file    ELSE_
  143. IF KY=Alt.K THEN GOSUB Toggle.Auto.Cap
  144. RETURN
  145. '''''''''''''''''''''''''end of main loop routines''''''''''''''''''''''''''
  146. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  147. '                     "Normal Key Pressed" routines:
  148.  
  149. 'AlphaNumeric.Key.Pressed .. Add the keypress (W$) to the line of text.
  150. 'Enter.Pressed ............. Process Enter keypress.
  151. 'Backspace.Pressed ......... Process Backspace keypress.
  152.  
  153.  AlphaNumeric.Key.Pressed:
  154. 1210'====================
  155. IF Auto.Cap THEN GOSUB Cap.First.Letter
  156. IF Insert THEN                                   'If Insert mode is on then
  157.   IF Char.Num < Max.Text.Len THEN                'if there is room then
  158.     IF Text.Len(Line.Num) = Max.Text.Len-1 THEN  'if this is end of the line
  159.       IF Wrap.On THEN                            'the if wrap is on, go move
  160.            GOSUB Wrap                        'the last word on the line
  161.     ELSEIF EEK>0 THEN                        'otherwise, make a noise to
  162.            SOUND EEK,EEK!                    'indicate the end of line
  163.            RETURN                            'and return.
  164.       END IF    'Note that in the Insert mode, the cusor is not necessarily
  165.     END IF      'at the end of the line when you run out of room above.
  166.     'Now that there is room, insert the character:
  167.     MID$(Text$(Line.Num),Char.Num) = W$ + MID$(Text$(Line.Num),Char.Num)
  168.     Char.Num=Char.Num+1
  169.     Text.Len(Line.Num)=Text.Len(Line.Num)+1
  170.     GOSUB Prnt
  171.     RETURN
  172.   END IF
  173. END IF
  174. 'Insert is not on, so overtype:
  175. MID$(Text$(Line.Num),Char.Num,1)=W$
  176. Char.Num=Char.Num+1
  177. PRINT W$;
  178. IF Char.Num > Text.Len(Line.Num) THEN_
  179.   Text.Len(Line.Num) = Char.Num-1
  180. IF Char.Num > Max.Text.Len THEN
  181.   IF Wrap.On THEN GOSUB Wrap
  182.   IF Char.Num > Max.Text.Len THEN
  183.     Char.Num = Max.Text.Len
  184.     IF EEK>0 THEN SOUND EEK,EEK!
  185.   END IF
  186. END IF
  187. RETURN
  188. ''''''
  189.  
  190.  Enter.Pressed:
  191. 1220'=========
  192. IF Line.Num < Max.Lines THEN      '  if this is not the last line then
  193.   IF  Insert_                     '    if Insert is on
  194.   AND Last.Line < Max.Lines THEN_ '    and there is still room
  195.     GOSUB Split.Line              '      then split the line at the
  196.   IF Indent.On THEN_              '      cursor point.
  197.   GOSUB Find.Indent
  198.   Line.Num=Line.Num+1             '  increment line pointer
  199.   Char.Num=Indent+1               '  move character pointer to start.
  200.   IF Line.Num > Last.Line THEN_   '  increment Last.Line count
  201.     Last.Line=Line.Num            '    if necessary.
  202.   IF Line.Num > Last.View.Line THEN_
  203.     GOSUB Scroll.Up
  204. END IF
  205. GOSUB Prnt
  206. RETURN
  207.  
  208.  Backspace.Pressed:
  209. 1230'=============
  210.             'backspace key deletes the character at the cursor
  211. IF Char.Num>1 THEN  '  and moves the following text left 1 space, adding
  212.   Char.Num=Char.Num-1 '   a space at the end to keep the line length right.
  213.   Text$(Line.Num)=LEFT$(Text$(Line.Num),Char.Num-1)_
  214.          +MID$(Text$(Line.Num),Char.Num+1)+" "
  215.   Text.Len(Line.Num)=Text.Len(Line.Num)-1
  216.   Char.Num=Char.Num-1
  217. END IF
  218. GOSUB Prnt
  219.  
  220. ''''''''''''''''''''end of main "Normal Key Pressed" Routines''''''''''''''''
  221. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  222. '                       "Special Key Pressed" Routines:
  223.  
  224.  Cursor.Right:
  225. 1310'========
  226. IF Char.Num < Max.Text.Len_
  227.   THEN Char.Num = Char.Num + 1
  228. RETURN
  229.  
  230.  Cursor.Left:
  231. 1320'=======
  232. IF Char.Num > 1 THEN_
  233.   Char.Num = Char.Num - 1
  234. RETURN
  235.  
  236.  Cursor.Up:
  237. 1330'=====
  238. GOSUB Find.Text.Len
  239. IF Line.Num > 1 THEN
  240.      IF Line.Num = First.View.Line THEN
  241.        GOSUB Scroll.down
  242.      END IF
  243.      IF  Line.Num > Last.Line_
  244.      AND Text.Len(Line.Num) <> 0 THEN
  245.        Last.Line = Line.Num
  246.      END IF
  247.      Line.Num = Line.Num - 1
  248.   ELSE IF EEK>0 THEN SOUND EEK,EEK!
  249. END IF
  250. RETURN
  251.  
  252.  Scroll.Down:
  253. 1331'-------
  254. First.View.Line = First.View.Line - 1
  255. Last.View.Line = Last.View.Line - 1
  256. current.line = Line.Num
  257. FOR Line.Num = First.View.Line TO Last.View.Line
  258.   GOSUB Prnt
  259. NEXT
  260. Line.Num = current.line
  261. RETURN
  262.  
  263.  Cursor.Dn:
  264. 1340'=====
  265. GOSUB Find.Text.Len
  266. IF Line.Num < Max.Lines THEN
  267.      IF Line.Num = Last.View.Line THEN_
  268.        GOSUB Scroll.Up
  269.      IF  Line.Num > Last.Line_
  270.      AND Text.Len(Line.Num) <> 0 THEN_
  271.        Last.Line = Line.Num
  272.      Line.Num = Line.Num + 1
  273.   ELSE IF EEK>0 THEN SOUND EEK,EEK!
  274. END IF
  275. RETURN
  276.  
  277.  Page.Up:
  278. '=======
  279. IF First.View.Line - Num.View.Lines => 1 THEN
  280.        First.View.Line = First.View.Line - Num.View.Lines
  281.        Line.Num = Line.Num - Num.View.Lines
  282.        Last.View.Line = Last.View.Line - Num.View.Lines
  283.   ELSE First.View.Line = 1
  284.        Line.Num = 1
  285.        Last.View.Line = Num.View.Lines
  286.        IF EEK>0 THEN SOUND EEK,EEK!
  287. END IF
  288. GOSUB Prnt.Lines
  289. RETURN
  290.  
  291.  Page.Dn:
  292. '=======
  293. IF Last.View.Line + Num.View.Lines <= Max.Lines THEN
  294.        Last.View.Line = Last.View.Line + Num.View.Lines
  295.        Line.Num = Line.Num + Num.View.Lines
  296.        First.View.Line = First.View.Line + Num.View.Lines
  297.   ELSE First.View.Line = Max.Lines - Num.View.Lines + 1
  298.        Last.View.Line = Max.Lines
  299.        Line.Num = Last.View.Line
  300.        IF EEK>0 THEN SOUND EEK,EEK!
  301. END IF
  302. GOSUB Prnt.Lines
  303. RETURN
  304.  
  305.  Move.Home:
  306. '=========
  307. IF Indent.On THEN_
  308.   GOSUB Find.Indent
  309. IF Char.Num > Indent+1_
  310.   THEN Char.Num=Indent+1_
  311.   ELSE Char.Num=1
  312. RETURN
  313.  
  314.  Move.to.End:
  315. '===========
  316. IF Text.Len(Line.Num) < Max.Text.Len_
  317.   THEN Char.Num = Text.Len(Line.Num) + 1_
  318.   ELSE Char.Num = Text.Len(Line.Num)
  319. RETURN
  320.  
  321.  Del.Char:
  322. '========
  323. IF Char.Num <= Text.Len(Line.Num) THEN
  324.        MID$(Text$(Line.Num), Char.Num)= _
  325.      MID$(Text$(Line.Num), Char.Num+1)+" "
  326.        Text.Len(Line.Num)=Text.Len(Line.Num)-1
  327.        GOSUB Prnt
  328.   ELSE dc.ln=Line.Num
  329.        GOSUB reform
  330.        Line.Num=dc.ln
  331. END IF
  332. RETURN
  333.  
  334.  Toggle.Insert:
  335. '=============
  336. IF Insert=NO_
  337.   THEN Insert=Yes:_
  338.        Locate ,,1,CU1,CU2_  'change to a half-block cursor shape
  339.   ELSE Insert=NO:_
  340.        Locate ,,,CU2  'change to an underline cursor shape
  341. RETURN
  342.  
  343.  Go.To.Next.Word:
  344. '===============
  345. IF Char.Num < Text.Len(Line.Num) + 1 THEN_
  346.   Char.Num = Char.Num + 1:_
  347.   WHILE Char.Num<Text.Len(Line.Num)+1_
  348.   AND Char.Num<Max.Text.Len_
  349.   AND (MID$(Text$(Line.Num),Char.Num-1,1)<>" "_
  350.   OR MID$(Text$(Line.Num),Char.Num-1,2)="  "):_
  351.     Char.Num=Char.Num-(Char.Num<Max.Text.Len):_
  352.   WEND
  353. RETURN
  354.  
  355.  Go.To.Prev.Word:
  356. '===============
  357. IF Char.Num> 2 THEN
  358.     Char.Num=Char.Num-1
  359.     WHILE Char.Num >2_
  360.     AND  ( MID$(Text$(Line.Num),Char.Num-1,1)<>" "_
  361.     OR MID$(Text$(Line.Num),Char.Num-1,2) ="  " )
  362.       IF Char.Num > 2 THEN
  363.     Char.Num = Char.Num - 1
  364.       END IF
  365.     WEND
  366.     IF  Char.Num = 2_
  367.     AND MID$(Text$(Line.Num),Char.Num, 1) <> " " THEN_
  368.       Char.Num=1
  369.   ELSE Char.Num=1
  370. END IF
  371. RETURN
  372.  
  373.  Del.to.EOL:   'delete from the cursor position to the end of the line
  374. '==========
  375. Text$(Line.Num)=LEFT$(Text$(Line.Num), Char.Num - 1)_
  376.            +SPACE$(Max.Text.Len - Char.Num + 1)
  377. Text.Len(Line.Num)=Char.Num-1
  378. GOSUB Prnt
  379. RETURN
  380.  
  381.  Go.To.File.Bgn:
  382. '==============
  383. IF First.View.Line=1 THEN IF EEK>0 THEN SOUND EEK,EEK!
  384. First.View.Line=1
  385. Last.View.Line = First.View.Line + Num.View.Lines -1
  386. GOSUB Prnt.Lines
  387. Line.Num=1
  388. RETURN
  389.  
  390.  Go.To.File.End:
  391. '==============
  392. IF Last.View.Line=Last.Line THEN IF EEK>0 THEN SOUND EEK,EEK!
  393. Last.View.Line=Last.line
  394. First.View.Line = Last.View.Line - Num.View.Lines + 1
  395. GOSUB Prnt.Lines
  396. Line.Num=Last.View.Line
  397. RETURN
  398.  
  399.  Define.Block:
  400. '============
  401. IF Line.Num > Block.Start_
  402. AND Block.Start > 0_
  403.   THEN Block.End = Line.Num_
  404.   ELSE Block.Start = Line.Num:_
  405.        IF Block.End=0_
  406.      THEN Block.End = Block.Start
  407. remember=Line.Num
  408. IF Line.Num < First.View.Line_
  409.   THEN Line.Num = First.View.Line_
  410.   ELSE Line.Num = Block.Start
  411. IF Block.End > Last.View.Line_
  412.   THEN b.e=Last.View.Line_
  413.   ELSE b.e=Block.End
  414. WHILE Line.Num <= b.e
  415.   Gosub Prnt
  416.   Line.Num=Line.Num+1
  417. WEND
  418. Line.Num=remember
  419. RETURN
  420.  
  421.  Erase.Block:
  422. '===========
  423. IF Block.Start=0 THEN RETURN
  424. block = Block.End - Block.Start + 1
  425. Last.Line = Last.Line - Block
  426. FOR l = Block.Start TO Last.Line
  427.   Text$(l) = Text$(l+block)
  428.   Text.Len(l) = Text.Len(l+block)
  429. NEXT
  430. FOR l=Last.Line+1 TO Last.Line+block
  431.   Text$(l) = SPACE$(Max.Text.Len)
  432.   Text.Len(l) = 0
  433. NEXT
  434. 'The purpose of this next section of code is to try to keep the cursor on the
  435. 'line it's on after deleting the lines in the block and to keep the cursor
  436. 'line from moving.
  437. IF  Block.Start => First.View.Line_
  438. AND Block.Start <= Last.View.Line THEN
  439.     IF Line.Num > Block.Start THEN_
  440.       IF Line.Num <= Block.End_
  441.     THEN Line.Num = Block.Start_
  442.     ELSE Line.Num = Line.Num - block:_
  443.          IF First.View.Line - block > 0 THEN_
  444.            First.View.Line = First.View.Line - block:_
  445.            Last.View.Line = First.View.Line + Num.View.Lines -1
  446.   ELSEIF Block.End <= Last.View.Line THEN
  447.     Line.Num = Line.Num - block
  448.     First.View.Line = First.View.Line - block
  449.     Last.View.Line = First.View.Line + Num.View.Lines -1
  450. END IF
  451. GOSUB Unmark.Block
  452. RETURN
  453.  
  454.  Paste.Block:
  455. '===========
  456. IF Block.Start = 0 THEN RETURN
  457. block = Block.End - Block.Start + 1
  458. IF Last.Line + block > Max.Lines THEN
  459.   Locate Msg.Line,25: PRINT SPACE$(45);: LOCATE Msg.Line,25: COLOR HL
  460.   PRINT "Not enough space left.";: COLOR FG
  461.   xxx$="": WHILE xxx$="": xxx$=INKEY$: WEND
  462.   LOCATE Msg.Line,25: PRINT SPACE$(40);
  463.   RETURN
  464. END IF
  465. FOR x=Last.Line+block TO Line.Num+block STEP -1
  466.   Text$(x) = Text$(x-block)
  467.   Text.Len(x) = Text.Len(x-block)
  468. NEXT
  469. FOR x=Line.Num TO Line.Num+block-1
  470.   Text$(x) = Text$(Block.Start + x-Line.Num)
  471.   Text.Len(x) = Text.Len(Block.Start + x-Line.Num)
  472. NEXT
  473. Last.Line = Last.Line + block
  474. GOSUB Prnt.Lines
  475. RETURN
  476.  
  477.  Unmark.Block:
  478. '============
  479. Block.Start=0
  480. Block.End=0
  481. GOSUB Prnt.Lines
  482. RETURN
  483.  
  484.  Del.Line:
  485. '========
  486. I=Line.Num
  487. FOR Line.Num=I TO Last.Line
  488.   Text$(Line.Num)=Text$(Line.Num+1)
  489.   Text.Len(Line.Num)=Text.Len(Line.Num+1)
  490.   IF Line.Num <= Last.View.Line THEN_
  491.     GOSUB Prnt
  492. NEXT
  493. Line.Num=I
  494. Last.Line=Last.Line-1
  495. RETURN
  496.  
  497.  Toggle.Indent:
  498. '=============
  499. IF Indent.On = Yes_
  500.   THEN Indent.On = No:_
  501.        Indent = 0_
  502.   ELSE Indent.On = Yes
  503. RETURN
  504.  
  505.  Find.Text:
  506. '=========
  507. LOCATE Msg.Line,22: PRINT SPACE$(45);:
  508. LOCATE Msg.Line,22: COLOR HL
  509. PRINT "Text to find: ";: COLOR FG: col=POS(0)
  510. GOSUB Get.input
  511. srch$=LEFT$(Text$(0), Text.Len(0))
  512. IF W$=Esc$ THEN LOCATE,22: PRINT SPACE$(45): RETURN
  513. WHILE l <> Line.Num_
  514. AND INSTR(Text$(l), srch$)=0
  515.   l=l+1
  516.   IF l > Last.Line THEN l=1
  517. WEND
  518. LOCATE Msg.Line,22: PRINT SPACE$(45);
  519. IF Line.Num <> l THEN
  520.   Line.Num=l
  521.   IF l > Last.View.Line_
  522.   OR l < First.View.Line THEN
  523.     IF Line.Num > (Num.View.Lines\2)_
  524.       THEN First.View.Line=Line.Num - Num.View.Lines\2_
  525.       ELSE First.View.Line=1
  526.     Last.View.Line=First.View.Line + Num.View.Lines - 1
  527.     GOSUB Prnt.Lines
  528.   END IF
  529.   Char.Num=Instr(Text$(l), srch$)
  530.   Locate First.Row+Line.Num-First.View.Line+1, First.Col+Char.Num-1,1
  531.   COLOR HL: PRINT srch$;: COLOR FG
  532. END IF
  533. RETURN
  534.  
  535.  Clear.Lines:
  536. '===========
  537. LOCATE Msg.Line,25: PRINT SPACE$(45);: LOCATE Msg.Line,25
  538. COLOR HL
  539. PRINT "Confirm: Clear all lines (y/n)";
  540. COLOR FG
  541. x$="": WHILE x$="": x$=INKEY$: WEND
  542. LOCATE Msg.Line,25: PRINT SPACE$(45);
  543. IF x$="y" OR x$="Y" THEN GOSUB Clear.mem: Fi$="": GOSUB Prnt.Lines
  544.  
  545. RETURN
  546.  
  547.  Clear.mem:
  548. '---------
  549. FOR x=1 TO Max.Lines
  550.   Text$(x)=SPACE$(Max.Text.Len)
  551.   Text.Len(x)=0
  552. NEXT
  553. Line.Num=1
  554. Char.Num=1
  555. First.View.Line=1
  556. Last.View.Lines=Num.View.Lines
  557. Last.Line=0
  558. RETURN
  559.  
  560.  New.File:
  561. '========
  562. LOCATE Msg.Line,25: PRINT SPACE$(45);
  563. LOCATE Msg.Line,25: COLOR HL
  564. PRINT "Confirm: Load new file (y/n)";
  565. COLOR FG
  566. x$="": WHILE x$="": x$=INKEY$: WEND
  567. LOCATE Msg.Line,25: PRINT SPACE$(45);
  568. IF x$="y" OR x$="Y" THEN
  569.   FOR x=1 TO Max.Lines
  570.     Text$(x)=SPACE$(Max.Text.Len)
  571.     Text.Len(x)=0
  572.   NEXT
  573.   GOSUB Load.File
  574. END IF
  575. RETURN
  576.  
  577.  Set.Rt.Margin:
  578. '=============
  579. LOCATE Msg.Line,25: PRINT SPACE$(45);: LOCATE ,25
  580. 'PRINT "Enter new right margin: ";
  581. PRINT "Feature not implemented yet.";
  582. 'Last.Col=0
  583. 'WHILE (Last.Col < First.Col) or (Last.Col > 80)
  584.   'Locate Msg.Line,48
  585.   LINE INPUT; x$
  586.   'Last.Col=val(x$)
  587. 'WEND
  588. LOCATE ,25: PRINT SPACE$(45);
  589. 'Max.Text.Len=Last.Col-First.Col+1
  590. RETURN
  591.  
  592.  Get.more.file:
  593. '=============
  594. IF Next.section=0 THEN RETURN
  595. IF End.of.big.file THEN
  596.   LOCATE Msg.Line,25: PRINT SPACE$(45);: LOCATE ,25
  597.   COLOR HL: PRINT "* * * END OF FILE * * *";
  598.   w$="": WHILE w$="": w$=INKEY$: WEND
  599.   LOCATE Msg.Line,25: PRINT SPACE$(45);: LOCATE ,25
  600.   RETURN
  601. END IF
  602. LOCATE Msg.Line,25: PRINT SPACE$(45);: LOCATE ,25
  603. COLOR HL: PRINT "* GETTING NEXT SECTION *";
  604. GOSUB Save.it
  605. GOSUB Clear.Mem
  606. 1801'
  607. OPEN Fi$ FOR INPUT AS #1
  608. FOR x = 1 TO Next.section
  609.   LINE INPUT #1, A$
  610. NEXT
  611. GOSUB Read.in.text
  612. First.View.Line=1
  613. Last.View.Line=Num.View.Lines
  614. Current.Line=1
  615. GOSUB Prnt.lines
  616. RETURN
  617.  
  618.  Toggle.Auto.Cap:
  619. '===============
  620. 'The following routine toggles Auto.cap & changes the Auto.cap status display.
  621. '  (Auto.cap capitalizes the first letter of each word.)
  622. Auto.Cap=NOT Auto.Cap:_
  623. LOCATE Msg.Line,69
  624. COLOR HL
  625. Print On.Off$(1+Auto.Cap);
  626. COLOR FG
  627. IF EEK>0 THEN SOUND EEK,EEK!
  628. RETURN
  629.  
  630. Cap.First.Letter:
  631. '================
  632. IF Char.Num > 1 THEN_
  633. IF INSTR(Delimiter$, MID$(Text$(Line.Num),Char.Num-1,1)) > 0 THEN_
  634.   IF W$>="a" AND W$<="z" THEN_
  635.     W$=CHR$(ASC(W$)-32)
  636. RETURN
  637.  
  638.  Wrap:
  639. '====
  640. IF Line.Num=Max.Lines THEN
  641.   LOCATE Msg.Line,28: COLOR HL
  642.   PRINT "No more lines allowed.  Press C.";
  643.   IF EEK>0 THEN SOUND EEK,EEK!
  644.   xxx$="" : WHILE xxx$<>"C" AND xxx$<>"c" : xxx$=INKEY$: WEND
  645.   LOCATE Msg.Line,28: COLOR FG
  646.   PRINT SPACE$(40);
  647.   Char.Num=Char.Num-1
  648.   Last.Line=Max.Lines
  649.   RETURN
  650. END IF
  651.  
  652. IF Insert THEN_
  653.   IF Char.Num < Text.Len(Line.Num)+1_
  654.     THEN GOTO Insert.Wrap_
  655.     ELSE IF Line.Num < Last.Line_
  656.        THEN GOSUB Move.lines.down
  657.  
  658. IF W$=" " THEN_
  659.   GOSUB Find.text.len:_
  660.   Split.point=Max.Text.Len:_
  661.   GOTO Incr.pointers
  662.  
  663. Split.Point = Max.Text.Len - 1
  664. WHILE MID$(Text$(Line.Num), Split.Point ,1) <> " " AND Split.Point > 2
  665.   Split.Point = Split.Point - 1
  666. WEND
  667.  
  668. IF Indent.On THEN
  669.     GOSUB Find.Indent
  670. END IF
  671. IF Split.Point = Indent THEN_
  672.   Split.Point = Max.Text.Len - 1
  673.  
  674. IF Split.Point > 1 THEN
  675.   MID$(Text$(Line.Num+1),Indent+1) = MID$(Text$(Line.Num),Split.Point+1)
  676.   MID$(Text$(Line.Num),Split.Point+1) = SPACE$(Max.Text.Len-Split.Point)
  677.   GOSUB Prnt
  678.   GOSUB Find.Text.Len
  679. END IF
  680.  
  681. Incr.pointers:
  682. Line.Num=Line.Num+1
  683. GOSUB Find.Text.Len
  684. IF Insert_
  685.   THEN Char.Num=Text.Len(Line.Num)+1:_
  686.        Last.Line=Last.Line+1_
  687.   ELSE Char.Num=Indent+Max.Text.Len-Split.Point+1
  688.        IF Line.Num > Last.Line THEN Last.Line=Line.Num
  689. IF Line.Num > Last.View.Line THEN
  690.   GOSUB Scroll.Up
  691. END IF
  692. GOSUB Prnt
  693.  
  694. RETURN
  695.  
  696. Insert.Wrap:
  697. '----------
  698. Original.char.pos = Char.Num
  699. Char.Num = Char.Num + 1
  700. WHILE MID$(Text$(Line.Num), Char.Num, 1)<>" "_
  701. AND   Char.Num < Max.Text.Len
  702.   Char.Num = Char.Num + 1
  703. WEND
  704. IF Char.Num = Max.Text.Len THEN Char.Num = Original.char.pos + 1
  705. GOSUB Split.line
  706. Char.Num= Original.char.pos
  707. RETURN
  708.  
  709.  Move.lines.down:
  710. '===============
  711. Current.Line = Line.Num
  712. FOR Line.Num = Last.Line+1 TO Current.Line+2 STEP -1
  713.   Text$(Line.Num) = Text$(Line.Num-1)
  714.   Text.Len(Line.Num) = Text.Len(Line.Num-1)
  715.   IF Line.Num <= Last.View.Line THEN
  716.     GOSUB Prnt
  717.   END IF
  718. NEXT
  719. Line.Num = Current.Line
  720. Text$(Line.Num+1) = SPACE$(Max.Text.Len)
  721. Text.Len(Line.Num+1) = 0
  722. Last.Line = Last.Line + 1
  723. RETURN
  724.  
  725. '''''''''''''''''end of "AlphaNumeric Key Pressed" subroutines'''''''''''''''
  726. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  727. 2000'                     General Program Subroutines:
  728.  
  729. 'Prnt ................... Assm. subroutine to print a line of text quickly.
  730. 'Prnt.Lines ............. Print all the text lines on the screen.
  731. 'Find.Text.Len .......... Finds last character in the line of text.
  732. 'Find.Indent ............ Starts new line at same first char. as prior line.
  733. 'Scroll.Up .............. Scroll lines up on the screen.
  734. 'Split.Line ............. Divide a line at the cursor position.
  735. 'Reform ................. Reform a paragraph from the cursor line.
  736.  
  737. 2010'
  738.  Prnt:
  739. '====
  740. IF Line.Num > Last.View.Line THEN GOSUB Scroll.Up
  741. DEF SEG
  742. addr=VARPTR(QPrint.CODE(0))
  743. prnt.txt$ = Text$(Line.Num)
  744. IF Line.Num=0 THEN
  745.   row = csrlin
  746.   CALL ABSOLUTE(Text$(0), row, Col, Attrib, addr)
  747.   RETURN
  748. END IF
  749. prnt.row = First.Row + Line.Num - First.View.Line + 1
  750. IF Block.Start > 0 THEN
  751.   IF Line.Num => Block.Start_
  752.   AND Line.Num <= Block.End_
  753.   AND Attrib=FG.BG_
  754.     THEN Attrib=BG.FG
  755. END IF
  756. CALL ABSOLUTE(prnt.txt$, prnt.row, First.Col, Attrib, addr)
  757. Attrib=FG.BG
  758. RETURN
  759.  
  760. 2020'
  761.  Prnt.Lines:
  762. '==========
  763. current.line=Line.Num
  764. FOR Line.Num = First.View.Line TO Last.View.Line
  765.   GOSUB Prnt
  766. NEXT
  767. Line.Num=current.line
  768. COLOR HL,BG: LOCATE Msg.Line,1
  769. PRINT "LINE:     CHAR:         Editing " Fi$".  Alt-H for Help.";_
  770.        SPACE$(80-POS(0));
  771. COLOR FG,BG
  772. RETURN
  773.  
  774. 2030'
  775.  Find.text.len:  'sets Text.Len to last non-blank character in a line
  776. '=============
  777. Text.Len(Line.Num)=Max.Text.Len
  778. WHILE MID$(Text$(Line.Num), Text.Len(Line.Num), 1) = " "_
  779. AND   Text.Len(Line.Num) > 1
  780.   Text.Len(Line.Num) = Text.Len(Line.Num) - 1
  781. WEND
  782. IF  Text.Len(Line.Num)=1_
  783. AND LEFT$(Text$(Line.Num),1)=" "_
  784.   THEN Text.Len(Line.Num)=0
  785. RETURN
  786.  
  787. 2040'
  788.  Find.Indent:   'for auto-indent: starts new line at same cursor position
  789. '===========    '  as the preceeding line.
  790. Indent=0
  791. IF Text$(Line.Num) <> SPACE$(Max.Text.Len) THEN
  792.   WHILE Indent+1 < Max.Text.Len_
  793.   AND   MID$( Text$(Line.Num), Indent+1, 1 ) = " "
  794.     Indent = Indent + 1
  795.   WEND
  796. END IF
  797. RETURN
  798.  
  799.  Scroll.Up:
  800. '=========
  801. First.View.Line = First.View.Line + 1
  802. Last.View.Line = Last.View.Line + 1
  803. current.line = Line.Num
  804. FOR Line.Num = First.View.Line TO Last.View.Line
  805.   GOSUB Prnt
  806. NEXT
  807. Line.Num = current.line
  808. RETURN
  809.  
  810.  Split.line:
  811. '==========
  812. GOSUB Move.lines.down
  813. IF Indent.On THEN GOSUB Find.Indent
  814. Line.Num = Line.Num + 1
  815. MID$(Text$(Line.Num), Indent+1) = MID$(Text$(Line.Num-1), Char.Num)
  816. GOSUB Find.text.len
  817. IF Line.Num > Last.View.Line THEN
  818.   GOSUB Scroll.Up
  819. END IF
  820. GOSUB Prnt
  821. 'Remove split-off text from current line:
  822. Line.Num=Line.Num-1
  823. MID$(Text$(Line.Num), Char.Num) = SPACE$(Max.Text.Len)
  824. GOSUB Find.text.len
  825. GOSUB Prnt
  826. RETURN
  827.  
  828.  Reform:   'to reform a paragraph from the cursor line to the end of para.
  829. '======
  830. IF Text$(Line.Num) = SPACE$(Max.Text.Len) THEN RETURN
  831.  
  832. 'find the end of the paragraph:
  833. IF Indent.On THEN GOSUB Find.Indent
  834. End.of.Para=Line.Num
  835. WHILE MID$(Text$(End.of.Para+1), Indent+1, 3) <> "   "_
  836. AND End.of.Para < Last.Line
  837.   End.of.Para = End.of.Para + 1
  838. WEND
  839. IF Line.Num=End.of.Para THEN RETURN
  840. IF KY=Del.Key THEN End.of.Para=Line.Num+1: KY=0
  841.  
  842. Remember.line.num=Line.Num
  843. Blanks=0
  844.  
  845. WHILE Line.Num < End.of.Para
  846.   Next.Line=Line.Num+1
  847.   IF Indent.On THEN
  848.     Line.Num=Next.Line
  849.     GOSUB Find.Indent
  850.     Line.Num=Next.Line-1
  851.   END IF
  852.  
  853.   'Combine two lines if possible:
  854.   WHILE (Text.Len(Line.Num) + Text.Len(Next.Line) - Indent) < Max.Text.Len_
  855.   AND   Next.Line <= End.of.Para
  856.     MID$(Text$(Line.Num), Text.Len(Line.Num)+2)_
  857.       =MID$(Text$(Next.Line), Indent+1, Text.Len(Next.Line)-Indent)
  858.     Text.Len(Line.Num) = Text.Len(Line.Num) + Text.Len(Next.Line)-Indent + 1
  859.     Next.Line = Next.Line + 1
  860.   WEND
  861.  
  862.   IF Next.Line > Line.Num+1 THEN
  863.     Move.up=Next.Line - Line.Num -1
  864.     FOR x=Line.Num+1 to End.of.Para-Move.up
  865.       Text$(x)=Text$(x+Move.up)
  866.       Text.Len(x)=Text.Len(x+Move.up)
  867.     NEXT
  868.     FOR x=End.of.Para-Move.up+1 to End.of.Para
  869.       Text$(x)=SPACE$(Max.Text.Len)
  870.       Text.Len(x)=0
  871.     NEXT
  872.     End.of.Para=End.of.Para-Move.up
  873.     Blanks=Blanks+Move.up
  874.     Next.Line=Line.Num+1
  875.   END IF
  876.  
  877.   'find next word in next line and move it up to the current line:
  878.   IF Next.Line <= End.of.Para THEN
  879.     Next.Word = INSTR(Indent+2,Text$(Next.Line)," ")-1
  880.  
  881.     IF  Text.Len(Line.Num) +1 + Next.Word-Indent <= Max.Text.Len_
  882.     AND Next.Word > 0 THEN
  883.  
  884.       WHILE INSTR(Next.Word+2, Text$(Next.Line), " ") > 0_
  885.       AND   INSTR(Next.Word+2, Text$(Next.Line), " ")-1 < Text.Len(Next.Line)_
  886.       AND   INSTR(Next.Word+2, Text$(Next.Line), " ")-Indent_
  887.            + Text.Len(Line.Num)_
  888.               <= Max.Text.Len
  889.          Next.Word = INSTR(Next.Word+2, Text$(Next.Line), " ")-1
  890.       WEND
  891.  
  892.       'move word up from next line:
  893.       MID$(Text$(Line.Num), Text.Len(Line.Num)+2) = _
  894.              MID$(Text$(Next.Line), Indent+1, Next.Word-Indent)
  895.       Text.Len(Line.Num)= Text.Len(Line.Num) + Next.Word-Indent + 1
  896.       MID$(Text$(Next.Line), Indent+1) = MID$(Text$(Next.Line), Next.Word+2)_
  897.                        + SPACE$(Next.Word+1-Indent)
  898.       Text.Len(Next.Line)=Text.Len(Next.Line)-(Next.Word+1-Indent)
  899.     END IF
  900.   END IF
  901.   GOSUB Prnt
  902.   Line.Num=Line.Num+1
  903. WEND
  904. GOSUB Prnt
  905.  
  906. 'Move up rest of lines in the file:
  907. IF End.of.Para <> Last.Line THEN
  908.   IF End.of.Para + Blanks <> Last.Line THEN
  909.     FOR Line.Num = End.of.Para+1 TO Last.Line-Blanks
  910.       Text$(Line.Num)=Text$(Line.Num+Blanks)
  911.       Text.Len(Line.Num)=Text.Len(Line.Num+Blanks)
  912.       IF Line.Num <= Last.View.Line THEN
  913.         GOSUB Prnt
  914.       END IF
  915.     NEXT
  916.   END IF
  917.   FOR Line.Num = Last.Line-Blanks+1 to Last.Line
  918.     Text$(Line.Num)=SPACE$(Max.Text.Len)
  919.     Text.Len(Line.Num)=0
  920.     IF Line.Num <= Last.View.Line THEN
  921.       GOSUB Prnt
  922.     END IF
  923.   NEXT
  924. END IF
  925. Line.Num=End.of.Para
  926. Last.Line=Last.Line-Blanks
  927. IF Line.Num+1 < Max.Lines THEN Line.Num=Line.Num+1
  928.  
  929. RETURN
  930.  
  931.  Get.input:
  932. 2080'=====
  933. l2080=Line.Num: Line.Num=0
  934. r2080=CSRLIN: c2080=POS(0)
  935. Text$(0)=space$(Max.Text.Len): W$="": Char.Num=1
  936. WHILE W$<>Entr$
  937.   IF LEN(W$) = 1 THEN GOSUB Normal.key.pressed
  938.   W$=""
  939.   LOCATE r2080,c2080+Char.num-1
  940.   WHILE W$=""
  941.     W$=INKEY$ : GOSUB Check.Lock.Status
  942.   WEND
  943. WEND
  944. Line.Num=r2080
  945. RETURN
  946.  
  947.  
  948. '------------------------end of main loop subroutines-----------------------
  949.  
  950. '-------------------------------help screen----------------------------------
  951. 3000'
  952. Help.Screen:
  953. l=First.Row+1: h$=""
  954. RESTORE help.data
  955. read h$
  956. WHILE h$<>"done"
  957.   DEF SEG: Addr=VARPTR(QPrint.CODE(0))
  958.   x$=SPACE$(Max.Text.Len)
  959.   FOR n=First.Row+1 TO Last.Row
  960.     CALL ABSOLUTE(x$, n, First.Col, Attrib, Addr)
  961.   NEXT
  962.   WHILE l < Last.Row AND h$<>"done"
  963.     x$=SPACE$(Max.Text.Len)  'this line and the next either cuts the line
  964.     MID$(x$,1)=h$   'down or pads with blanks to fit the available space.
  965.     DEF SEG
  966.     Addr=VARPTR(QPrint.CODE(0))
  967.     CALL ABSOLUTE(x$, l, First.Col, Attrib, Addr)
  968.     l=l+1
  969.     READ h$
  970.   WEND
  971.   xxx$="": while xxx$="": xxx$=inkey$: wend
  972.   l=First.Row+1
  973. WEND
  974. GOSUB Prnt.Lines
  975. RETURN
  976.  
  977. help.data:
  978. data "Alt-B defines the beginning/end of a block of lines."
  979. data "Alt-C clears all lines."
  980. data "Alt-D deletes the line at the cursor position."
  981. data "Alt-E erases a block of lines."
  982. data "Alt-F finds specified text"
  983. data "Alt-G gets next section of a large file."
  984. data "Alt-I toggles auto-indent."
  985. data "Alt-K automatically caps the first letter of each word."
  986. data "Alt-M set right Margin."
  987. data "Alt-N to load a new file."
  988. data "Alt-P pastes (copies) a block of lines."
  989. data "Alt-R reforms paragraph from the current line down."
  990. data "Alt-U unmarks a block of lines."
  991. data "Alt-W toggles word-wrap on/off."
  992. data "Alt-X save and exit."
  993. data "Esc   exit without saving."
  994. data "Ctrl-End deletes from the cursor to the end of the line."
  995. data "Ins  toggles Insert mode."
  996. data "ENTER pressed in the Insert mode splits a line at the cursor position."
  997. data "Del at end of text joins two lines."
  998. data "Cursor movement keys:"
  999. data "    Up, Down, Left, Right."
  1000. data "    Home, End - Move to start or end of text. Again: start/end of line."
  1001. data "    Ctrl-Left Ctrl-Right - move cursor 1 word left or right."
  1002. data "done"
  1003. '--------------------------end of help screen--------------------------------
  1004.  
  1005. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  1006.  
  1007.              Initialize.Parameters:
  1008. 4000'
  1009. 'Get DOS command line parameters:
  1010.  
  1011. CMD$=command$
  1012. 'if /E present, use EMS memory:
  1013. IF INSTR(CMD$, "/E") or INSTR(CMD$, "/e") THEN TSR=-1
  1014. 'if /S present, use disk swapping:
  1015. s= INSTR(CMD$, "/S"): if s=0 then s=INSTR(CMD$, "/s")
  1016. IF s>0 THEN
  1017.   TSR = -1
  1018.   operation=7
  1019.   DIR$=MID$(CMD$, s+2)
  1020.   kshift=varptr(DIR$)
  1021.   call stayres(operation, kscan, kshift, ecode)
  1022.   IF ecode=3 then
  1023.     PRINT "Must use DOS 3 for disk swapping.";
  1024.     x$="": WHILE x$="": x$=INKEY$: WEND
  1025.     END
  1026.   END IF
  1027.   IF ecode THEN
  1028.     PRINT "Can't use " dir$;
  1029.     x$="": WHILE x$="": x$=INKEY$: WEND
  1030.     END
  1031.   END IF
  1032. END IF
  1033.  
  1034. 'Variables for ForeGround, HighLight & BackGround colors:
  1035. f=INSTR(CMD$, "/FG"): if f=0 then f=INSTR(CMD$, "/fg")
  1036. b=INSTR(CMD$, "/BG"): if b=0 then b=INSTR(CMD$, "/bg")
  1037. h=INSTR(CMD$, "/HL"): if h=0 then h=INSTR(CMD$, "/hl")
  1038. IF f>0 THEN FG=VAL(MID$(CMD$,f+3,2)) ELSE FG=7
  1039. IF b>0 THEN BG=VAL(MID$(CMD$,b+3,2)) ELSE BG=0
  1040. IF h>0 THEN HL=VAL(MID$(CMD$,h+3,2)) ELSE HL=15
  1041.  
  1042. 'These tones are used to indicate change in -Lock status, etc:
  1043. IF INSTR(CMD$, "/q")=0 AND INSTR(CMD$, "/Q")=0 THEN
  1044.   Lock.Tone=400
  1045.   Duration!= .4
  1046.   EEK=4000
  1047.   EEK!=.04
  1048. END IF
  1049. ''''''''''''''''''''end of command line processing''''''''''''''''''
  1050.  
  1051.  
  1052. Char.Num=1   'points to cursor position within edit area.
  1053. Line.Num=1   'points to cursor row within edit area.
  1054. Last.Line=1  'last line with text in it.
  1055. First.View.Line=1   'line number of top line in edit area.
  1056. Last.View.Line=Last.Row-First.Row+1   'line number of last line in edit area.
  1057. Num.View.Lines = Last.View.Line       'max lines allowed in edit area.
  1058. Max.Text.Len=Last.Col-First.Col+1     'max line length.
  1059. First.Row=First.Row-1  'for easier computations.
  1060.  
  1061. Yes= -1
  1062. No =  0
  1063.  
  1064. Wrap.On = Yes   'word wrap may be toggled, but starts turned on.
  1065. Indent.On = Yes 'turn on automatic Indents.
  1066.  
  1067. FOR x=1 TO Max.Lines
  1068.   Text$(x)=SPACE$(Max.Text.Len)
  1069. NEXT
  1070.  
  1071. WIDTH 80
  1072. DEF SEG=0
  1073. COLR= (PEEK(&H410) AND &H30)<>&H30
  1074. DEF SEG
  1075. IF COLR THEN_ 'cursor shape definition:
  1076.        CU1=4:_
  1077.        CU2=7_
  1078.   ELSE CU1=11:_
  1079.        CU2=13
  1080.  
  1081. Delimiter$ = " ,.-;:=+(<#*{['/" + CHR$(34)
  1082.  
  1083. 'variables for displaying -Lock status:
  1084.  
  1085. Locks$(0)=STRING$(7," ")
  1086. Locks$(1)=STRING$(4," ")+"NUM"
  1087. Locks$(2)="CAP"+STRING$(4," ")
  1088. Locks$(3)="CAP"+CHR$(32)+"NUM"
  1089. On.Off$(0)="ON "
  1090. On.Off$(1)="OFF"
  1091.  
  1092. Entr$=CHR$(13)
  1093. Bksp$=CHR$(8)
  1094. Esc$=CHR$(27)
  1095. Entr.symbol$=" "+CHR$(17)+STRING$(2,196)+CHR$(217)+" "  'not used this pgm.
  1096.  
  1097. 'key scan codes:
  1098.  
  1099. LF.Cursor=75
  1100. RT.Cursor=77
  1101. Ctrl.LF=115
  1102. Ctrl.RT=116
  1103.  
  1104. UP.Cursor=72
  1105. DN.Cursor=80
  1106. PG.UP=73
  1107. PG.DN=81
  1108. Ctrl.PgUp=132
  1109. Ctrl.PgDn=118
  1110.  
  1111. Home=71
  1112. Ctrl.Home=119
  1113. End.Key=79
  1114. Ctrl.End=117
  1115. Ins.Key=82
  1116. Del.Key=83
  1117. ESC=27
  1118. Alt.B=48  'define block of lines
  1119. Alt.C=46  'clear all lines
  1120. Alt.D=32  'delete line at cursor
  1121. Alt.E=18  'erase block
  1122. Alt.F=33  'find text
  1123. Alt.G=34  'get next file section
  1124. Alt.H=35  'display help
  1125. Alt.I=23  'toggle auto-indent
  1126. Alt.K=37  'toggle auto-kap
  1127. Alt.L=38  '
  1128. Alt.M=50  'set right Margin
  1129. Alt.N=49  'new file
  1130. Alt.P=25  'paste block
  1131. Alt.R=19  'reform paragraph
  1132. Alt.S=31  'save file
  1133. Alt.U=22  'unmark block
  1134. Alt.W=17  'toggle word wrap
  1135. Alt.X=45  'exit
  1136.  
  1137. 'attribute codes FOR the asm subroutine:
  1138. FG.BG=FG+(BG AND 7)*16  'normal foreground-background
  1139. HL.BG=HL+(BG AND 7)*16  'highlighted foreground-normal background 'not used
  1140. BG.FG=BG+(FG AND 7)*16  'inverse video   'not used in this program
  1141.  
  1142. Attrib=FG.BG  'Attribute is normally set to the foreground/background colors.
  1143.           'The Attrib variable is used in the quick-print subroutine.
  1144.  
  1145. RESTORE Qprint.data
  1146. DEF SEG
  1147. FOR J=0 TO 106
  1148.   READ H$
  1149.   C$="&H"+H$
  1150.   X=VAL(C$)
  1151.   POKE (VARPTR(QPrint.CODE(0))+J),X
  1152. NEXT
  1153.  Qprint.data:
  1154. '-----------
  1155. DATA 55, 8B,EC, 8B,5E,08, 8B,3F, 4F, 8B,5E,0A, 8B,07, 48
  1156. DATA 8B,5E,0C, B5,00, 8A,0F, 80,F9,00, 74,37, 8B,77,02, BB,40,00
  1157. DATA 8E,C3, 26, F7,26,4A,00, 03,F8, D1,E7, 26, 8B,16,63,00
  1158. DATA 83,C2,06, B8,00,B8, 26, 8B,1E,10,00, 81,E3,30,00
  1159. DATA 83,FB,30, 75,03, B8,00,B0, 8B,5E,06, 8A,3F, 8E,C0
  1160. DATA E8,04,00, 5D, CA,08,00, AC, 8A,D8, EC, A8,01, 75,FB, FA, EC
  1161. DATA A8,01, 74,FB, 8B,C3, AB, FB, E2,EC, C3
  1162.  
  1163. LOCATE ,,1
  1164.  
  1165. IF TSR THEN     'This implements MicroHelp's code to make editor resident.
  1166.   Operation=0   ' can be purchased from MicroHelp.
  1167.   Kshift=12   '  \___Ctrl-Alt-E is the hot key. See StayRes manual to change.
  1168.   Kscan=18    '  /
  1169.   Ecode=100
  1170.   call stayRes(Operation, Kscan, Kshift, Ecode)
  1171.   IF Ecode > 0 THEN PRINT "StayRes Error" Ecode: stop
  1172. END IF
  1173. RETURN
  1174.  
  1175. 'end of Initialize.Parameters
  1176. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  1177. 5000
  1178.                   Load.File:
  1179.  
  1180.  'have to have a line number for error trapping
  1181. GOSUB Get.filename
  1182. IF f$<>"" THEN GOSUB Load.it
  1183. GOSUB Prnt.Lines
  1184. RETURN
  1185.  
  1186.  Get.filename:
  1187. '------------
  1188. COLOR FG,BG
  1189. CLS : f$="": New.Fi$="" : keep.going = yes
  1190. WHILE keep.going
  1191.   IF f$<>"" THEN FILES f$
  1192.   PRINT
  1193.   PRINT "Enter DIR or DIR A:FILENAME or DIR B:*.DOC, etc, for directories."
  1194.   PRINT "Just press ENTER to edit a new file or a file already in memory."
  1195.   IF NOT TSR THEN PRINT "Enter QUIT to exit the program."
  1196.   PRINT: PRINT "Name of file to edit: "; : col=pos(0)
  1197.   GOSUB Get.input
  1198.   f$=LEFT$(text$(0), Text.Len(0))
  1199.   IF NOT TSR THEN IF f$="quit" OR f$="QUIT" THEN CLS : END
  1200.   IF LEFT$(f$,3)="DIR" OR LEFT$(f$,3)="dir" THEN
  1201.      IF LEN(f$) < 5 THEN
  1202.         f$="*.*"
  1203.        ELSE f$=mid$(f$,5)
  1204.      END IF
  1205.     ELSE keep.going = no
  1206.   END IF
  1207. WEND
  1208. RETURN
  1209.  
  1210.  Load.it:
  1211. '-------
  1212. IF Last.Line > 0 THEN GOSUB Clear.mem
  1213. Fi$=f$
  1214. OPEN Fi$ FOR INPUT AS #1
  1215. PRINT: PRINT: PRINT "Loading " Fi$: PRINT
  1216. Next.section=0
  1217. Trunc$="0"
  1218.  Read.in.text:
  1219. Start.section = Next.section
  1220. WHILE NOT EOF(1) AND Next.section = Start.section
  1221.   Last.Line = Last.Line + 1
  1222.   LINE INPUT #1, x$
  1223.   MID$(Text$(Last.Line),1)=x$
  1224.   Line.Num=Last.Line
  1225.   GOSUB Find.Text.Len
  1226.   IF LEN(x$) > Max.Text.Len THEN IF Trunc$<>"1" THEN GOSUB Long.line
  1227.   IF Last.Line => Max.Lines THEN GOSUB Big.file
  1228. WEND
  1229. CLOSE: Line.Num=1: Char.Num=1
  1230. IF Next.section > 0 THEN_
  1231.   IF Start.Section = Next.section_
  1232.     THEN End.of.big.file = yes:_
  1233.      Next.section=Last.line+1_
  1234.     ELSE End.of.big.file = no
  1235. RETURN
  1236.  
  1237.  Big.file:
  1238. '--------
  1239. IF Next.section = 0 THEN
  1240.   PRINT "File exceeds the maximum of" Max.Lines " lines (per section)."
  1241.   PRINT "At the present, MyEd allows only limited editing of longer files."
  1242.   PRINT "You can edit one piece of the file at a time, but not go back without
  1243.   PRINT "restarting the file over (ie: Alt-X).  A limit of 50 new lines can be
  1244.   PRINT "added to each section without starting over or deleting more lines."
  1245.   PRINT "The process of saving 500 lines and loading the next 500 lines is"
  1246.   PRINT "pretty slow, but it does make it possible to edit any size file."
  1247.   PRINT "To Get the next section while editing, press Alt-G."
  1248.   PRINT: PRINT "Make sure that enough disk space is available and"
  1249.   PRINT "enter drive and filename to use for new file: "; : col=POS(0)
  1250.   GOSUB get.input: PRINT
  1251.   New.Fi$=LEFT$(text$(0),Text.Len(0))
  1252.   OPEN New.Fi$ FOR OUTPUT AS #2: CLOSE #2  'make sure filename is ok.
  1253. END IF
  1254. Next.section = Start.section + Max.Lines-50
  1255. FOR x=Max.Lines-49 to Max.Lines
  1256.   Text$(x)=SPACE$(Max.Text.Len)
  1257.   Text.Len(x)=0
  1258. NEXT
  1259. Last.Line=450
  1260. RETURN
  1261.  
  1262.  Long.line:
  1263. '---------
  1264. WHILE INSTR("123",Trunc$)=0
  1265.   PRINT left$(x$, Max.Text.Len);
  1266.   COLOR BG,FG: PRINT mid$(x$, Max.Text.Len+1): COLOR FG,BG
  1267.   PRINT: PRINT "Line exceeds maximum line length of"Max.Text.Len".
  1268.   PRINT "1-Truncate  2-Wrap  3-Abort: ";
  1269.   Trunc$="": WHILE Trunc$="": Trunc$=INKEY$: WEND: PRINT
  1270.   PRINT "Keep asking each time? (y/n): ";
  1271.   ka$="": WHILE ka$="": ka$=INKEY$: WEND: PRINT
  1272. WEND
  1273. IF Trunc$="3" THEN RETURN 5000
  1274. IF Trunc$="2" AND Last.Line < Max.Lines THEN
  1275.   Last.Line = Last.Line +1
  1276.   MID$(Text$(Last.Line),1) = MID$(x$, Max.Text.Len+1)
  1277.   Line.Num=Last.Line
  1278.   GOSUB Find.Text.Len
  1279. END IF
  1280. IF INSTR("Nn", ka$)=0 THEN Trunc$="0"
  1281. RETURN
  1282.  
  1283. '''''''''''''''''''''''''''''end of Load.File''''''''''''''''''''''''''''''''
  1284. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  1285. 6000'                           Save file:
  1286.  Save.exit:
  1287.  
  1288. IF W$=Esc$ THEN_
  1289.   IF NOT TSR_
  1290.     THEN CLS: END_
  1291.     ELSE GOTO Exit.to.DOS
  1292.  
  1293. LOCATE Msg.Line,25: PRINT SPACE$(40);
  1294. LOCATE Msg.Line,25: ans$=""
  1295.  
  1296. IF New.Fi$<>"" THEN
  1297.   COLOR HL+15: PRINT "        Saving " New.fi$;
  1298.   GOTO Save.it
  1299. END IF
  1300.  
  1301. IF Fi$ <> "" THEN
  1302.   COLOR HL: PRINT "Save file as " Fi$ " (y/n) ";: COLOR FG
  1303.   ans$="": WHILE ans$="": ans$=INKEY$: WEND
  1304.   LOCATE Msg.Line,25: PRINT SPACE$(40);
  1305. END IF
  1306.  
  1307. IF ans$ <> "y" AND ans$ <> "Y" THEN
  1308.   LOCATE Msg.Line,25: COLOR HL
  1309.   PRINT "Enter new filename:  ";: COLOR FG : col=POS(0)
  1310.   GOSUB Get.input
  1311.   Fi$=LEFT$(Text$(0), Text.Len(0))
  1312.   IF Fi$="" THEN
  1313.     LOCATE Msg.Line,25: PRINT SPACE$(40);
  1314.     LOCATE Msg.Line,25: COLOR HL
  1315.     PRINT "Quit without saving (y/n)";
  1316.     COLOR FG
  1317.     abort$="": WHILE abort$="": abort$=INKEY$: WEND
  1318.     IF abort$<>"Y" AND abort$<>"y" THEN
  1319.        LOCATE Msg.Line,25: PRINT SPACE$(40);:
  1320.        KY=0
  1321.        RETURN
  1322.       ELSE GOTO Exit.to.DOS
  1323.     END IF
  1324.   END IF
  1325. END IF
  1326. LOCATE Msg.Line,25: PRINT SPACE$(40);
  1327. LOCATE Msg.Line,25: COLOR HL: PRINT "       Saving " Fi$;
  1328.  
  1329.  save.it:
  1330. IF New.Fi$<>""_
  1331.   THEN OPEN New.Fi$ FOR APPEND AS #1_
  1332.   ELSE OPEN Fi$ FOR OUTPUT AS #1
  1333. FOR x=1 TO Last.Line
  1334.   PRINT #1, LEFT$(Text$(x), Text.Len(x))
  1335. NEXT
  1336. CLOSE
  1337.  
  1338. IF KY=Alt.G THEN RETURN
  1339.  
  1340. IF New.Fi$<>"" THEN_
  1341.    IF NOT End.of.big.file THEN GOSUB Close.big.file
  1342.  
  1343.  Exit.to.DOS:
  1344. '-----------
  1345. LOCATE Msg.Line,25: PRINT SPACE$(40);
  1346. IF TSR THEN call stayres(Operation, Kscan, Kshift, Ecode):_
  1347.         GOSUB Prnt.Lines
  1348. RETURN
  1349.  
  1350.  Close.big.file:
  1351. '--------------
  1352. 6500'
  1353. OPEN Fi$ FOR INPUT AS #1
  1354. FOR x=1 TO Next.section : LINE INPUT #1, x$: NEXT
  1355. OPEN New.Fi$ FOR APPEND AS #2
  1356. WHILE NOT EOF(1)
  1357.   LINE INPUT #1, A$
  1358.   PRINT #2, A$
  1359. WEND
  1360. CLOSE
  1361. RETURN
  1362.  
  1363.  Err.Trap:
  1364. '========
  1365. 6600 CLOSE
  1366. LOCATE Msg.Line,25:PRINT SPACE$(45);:LOCATE Msg.Line,25
  1367. COLOR HL
  1368. IF ERR=64 THEN
  1369.      PRINT "Bad file name";
  1370.   ELSEIF ERR=61 THEN
  1371.      PRINT "Disk full";
  1372.   ELSEIF ERR=72 THEN
  1373.      PRINT "Disk media error";
  1374.   ELSEIF ERR=71 THEN
  1375.      PRINT "Drive not ready";
  1376.   ELSEIF ERR=53 THEN
  1377.      PRINT "File not found";
  1378.   ELSEIF ERR=7 OR ERR=14 THEN
  1379.      PRINT "Out of memory";
  1380.   ELSEIF ERR=76 THEN
  1381.      PRINT "Path not found";
  1382.   ELSEIF ERR=70 THEN
  1383.      PRINT "Disk/file write-protected";
  1384.   ELSE PRINT "Error number" ERR; "in line number" ERL;
  1385. END IF
  1386. COLOR FG: xe$=""
  1387. WHILE xe$="": xe$=INKEY$: WEND
  1388. IF ERL=1801 THEN RESUME 1801
  1389. IF ERL=5000 THEN f$="": RESUME 5000
  1390. IF ERL=6000 THEN RESUME 6000
  1391. IF ERL=6500 THEN RESUME 6500
  1392.