home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / LASER / FPC35_5.ZIP / FPCSRC.ZIP / SEDITOR.SEQ < prev    next >
Encoding:
Text File  |  1989-09-26  |  71.9 KB  |  1,905 lines

  1. \ SEDITOR.SEQ   Sequential EDitor          Written by 1987 Tom Zimmer
  2.  
  3. comment:
  4.  
  5. Hello -
  6.  
  7.         SED the Sequential EDitor was written by Tom Zimmer.
  8.  
  9.         SED is released into the Public Domain. It is included as an
  10.         imbedded portion of the F-PC Forth system, and may be used as
  11.         needed to develop programs on that system. SED is provided in
  12.         source form in the F-PC system to allow you the ability to change
  13.         SEDs characteristics. The Forth system F-PC is also in the public
  14.         domain, and as such you may do with F-PC and SED as you wish.
  15.  
  16.                                         Tom Zimmer
  17.  
  18. comment;
  19.  
  20. decimal         \ always use default to decimal
  21.  
  22. editor definitions
  23.  
  24. : statusline first.textline 1- ;
  25.  
  26.   ' first.textline alias helpline
  27.             250 constant ch/l
  28.                187 value helpkey        \ default value is F1 key
  29.  
  30.                  0 value torig          \ origin of text in text segment
  31.            2573 constant crlfval        \ value of line terminator CRLF.
  32.            8224 constant blbl           \ value of two blanks.
  33.             255 constant linebuf.len
  34.              12 constant formfeed
  35.              55 constant prtlines       \ print lines per page
  36.  
  37. 0 value keychar                         \ key just pressed
  38. 0 value changed                         \ edit changed flag
  39. 0 value ?eddone                         \ is the edit done?
  40. 0 value imode                           \ insert mode flag
  41. 0 value lmrgn
  42. 0 value lchng                           \ line changed flag
  43. 0 value marking                         \ marked lines shown in reverse?
  44. 0 value markdone
  45. 0 value markfst
  46. 0 value markstrt                        \ mark/get line #
  47. 0 value markend
  48. 0 value markchar                        \ mark/get character offset
  49. 0 value etabsize       8 =: etabsize    \ default to 8 char increment
  50. 0 value ermargin     132 =: ermargin    \ default to 132 char right margin
  51. 0 value updated                         \ have we updated to disk yet?
  52. 0 value ldel.cnt                        \ count of line deletes
  53. 0 value leavesave
  54. 0 value leavenow                        \ leave editor now, don't unnest
  55. 0 value pop-extra
  56. 0 value %read-from
  57.  
  58. true value ?warnexit
  59.  
  60.  
  61. headerless
  62.  
  63. 0 value ?border
  64. 0 value lookflg         \ did we find anything last time?
  65. 0 value wrapped
  66. 0 value wraplen
  67. 0 value wraploc
  68. 0 value filtering       \ are we looking for ESC and Alt-F10?
  69.  
  70. create nfil  2 c, 13 c, 10 c,   \ A counted empty file string
  71.  
  72. headers
  73.  
  74. 0 value linelen
  75.  
  76. create slook.buf   32 allot     \ search buffer
  77.        slook.buf   32 blank 1 slook.buf c!
  78.  
  79. 248 value hyperdest     \ hypertext character, marks a link destination
  80. 249 value hyperchar     \ hypertext character, marks a source link
  81.  
  82. defer showstat
  83. defer sbutton   ' beep is sbutton       \ screen editor button handler
  84.  
  85. headerless
  86.  
  87. defer exit.edit         ' quit          is exit.edit  \ default to just quit
  88. defer normkey           ' bl            is normkey
  89. defer normfilter        ' noop          is normfilter
  90. defer normbgstuff       ' noop          is normbgstuff
  91. defer normbutton        ' noop          is normbutton
  92. defer ins-cursor        ' big-cursor    is ins-cursor
  93. defer reset_defered     \ set later to DEFERRESET
  94.  
  95. 0 value vstaton
  96. 0 value statcnt
  97.  
  98. headers
  99.  
  100. \ : ?capslock     ( --- f1 ) 0 $417 c@l $40 and 0<> ;
  101. : ?altkey       ( --- f1 ) 0 $417 c@l $08 and 0<> ;
  102. : ?ctrlkey      ( --- f1 ) 0 $417 c@l $04 and 0<> ;
  103. : ?shiftkey     ( --- f1 ) 0 $417 c@l $02 and 0<> ;
  104.  
  105. create  linebuf ( linebuf.len ) 300 allot
  106.         linebuf ( linebuf.len ) 300 blank
  107.  
  108. headerless
  109.  
  110. create split.buf linebuf.len allot split.buf linebuf.len blank
  111. create  wrap.buf linebuf.len allot  wrap.buf linebuf.len blank
  112. create fdbuf     66          allot fdbuf     66          erase
  113.  
  114. 0 value csaveflg        \ are we saving characters
  115.  
  116. 0 value ldel.buf
  117.  
  118. create --'s.buf 132 allot
  119.  
  120. : -s    ( n1 --- )
  121.         --'s.buf 132 ?browse if $cd else $c4 then fill
  122.         --'s.buf swap type ;
  123.  
  124. : gremit create c, does> 1 type ;
  125.  
  126. $c0 gremit |.   $c4 gremit --   $b3 gremit |    $d9 gremit .|
  127. $bf gremit '|   $da gremit |'
  128.  
  129. $c8 gremit ||.  $cd gremit ==   $ba gremit ||   $bc gremit .||
  130. $bb gremit '||  $c9 gremit ||'
  131.  
  132. : .g|           ( --- )         \ display a virtical bar character
  133.                 ?browse
  134.                 if      ||
  135.                 else    |
  136.                 then    ;
  137.  
  138. : .g'|          ( --- )
  139.                 ?browse
  140.                 if      '||
  141.                 else    '|
  142.                 then    ;
  143.  
  144. : .g|.          ( --- )
  145.                 ?browse
  146.                 if      ||.
  147.                 else    |.
  148.                 then    ;
  149.  
  150. : .g.|          ( --- )
  151.                 ?browse
  152.                 if      .||
  153.                 else    .|
  154.                 then    ;
  155.  
  156. : .g|'          ( --- )
  157.                 ?browse
  158.                 if      ||'
  159.                 else    |'
  160.                 then    ;
  161.  
  162. : .l            ( n1 n2 --- )   \ Print left justified in fld
  163.                 >r (u.) dup>r type r> r> swap - spaces ;
  164.  
  165. headers
  166.  
  167. : emptykbd  ( --- )     \ empty any keyboard typeahead
  168.             ?DOSIO
  169.             if    begin       key?
  170.                   while       (key) drop
  171.                   repeat
  172.             else  begin       0 $41A @L
  173.                               0 $41C @L - abs 2 >     \ keyboard depth > 1 key
  174.                   while       bioskey drop
  175.                   repeat
  176.             then  ;
  177.  
  178.                 \ $02 = Shift key, $08 = Alt key, $40 = Caps lock.
  179.  
  180. : modified      ( --- )         \ mark line and text as having been modified.
  181.                 on> lchng on> changed ;
  182.  
  183. create  end-spcs 80 allot
  184.         end-spcs 80 177 fill    \ 177 is a nice gray character.
  185.  
  186. : edeeol        ( --- )         \ clear the screen line.
  187.                 window.right @> #out - spaces ;
  188.  
  189. : end-eeol      ( --- )         \ clear the screen line to gray
  190.                 ?DOSIO
  191.                 if      @> #out @> #line at
  192.                 then    window.right @> #out -
  193.                 0max    dup 80 <
  194.                 if      end-spcs swap type
  195.                 else    80 /mod 0
  196.                         ?do     end-spcs   80 type
  197.                         loop    end-spcs swap type
  198.                 then    ;
  199.  
  200. : creeol        ( --- )         \ erase next line.
  201.                 cr edeeol first.textcol @> #line at ;
  202.  
  203. : erase.bottom  ( --- )
  204.                 first.textcol @> #line rows 1- over - 1 max 0
  205.                 do creeol loop at ;
  206.  
  207. headerless
  208.  
  209. : terminate.edit        ( --- )
  210.                 creeol creeol ." Leaving now...." creeol
  211.                 erase.bottom exit.edit ;
  212.  
  213. : ?terror       ( f1 a1 n1 --- )        \ handle errors
  214.                 rot
  215.                 if      creeol type
  216.                         reset_defered
  217.                         terminate.edit
  218.                 else    2drop then    ;
  219.  
  220. : ?<>bak        ( --- )                 \ verify current file is not a .BAK
  221.                 ed1hndl handle>ext 1+ " BAK" caps-comp 0=
  222.                 " Can't edit files with ext .BAK" ?terror
  223.                 ed1hndl handle>ext 1+ " $$$" caps-comp 0=
  224.                 " Can't edit files with ext .$$$" ?terror ;
  225.  
  226. : set.newfile   ( --- )         \ setup memory for a new file
  227.                 creeol ."    New File Created "  creeol
  228.                 0.2 currentsize 2!
  229.                 off> curline                    \ clear current line
  230.                 off> lastline                   \ and total lines
  231.                 tsegb lineptr tl:!              \ first segment setup
  232.                 ?cs: nfil tsegb 0 3 cmovel      \ move in a counted CRLF $
  233.                 incr> lastline                  \ inrement total lines
  234.                 5 tenths ;
  235.  
  236. : ?softerror    ( bool a1 n1 --- )      \ bool = false if OK, else type msg
  237.                 rot
  238.                 if      >r 36 r@ 2/ - 6 over r@ + 2 + 9 box&fill
  239.                         space r> \type
  240.                         bcr ."   \1 Press - \2 ESC "
  241.                         cursor-off
  242.                         begin   beep
  243.                                 key 27 ( ESC ) =
  244.                         until
  245.                         cursor-on
  246.                 else    2drop
  247.                 then    ;
  248.  
  249. headers
  250.  
  251. : placeline     ( a1 --- )
  252.                 >r                      \ save line address
  253.                 ?cs: r@                 \ moving from line seg & address
  254.                 lineptr tl:@ 0          \ to text line seg and offset = 0
  255.                 r@ c@ len-accum         \ sum in length to total file size
  256.                 1+ cmovel               \ move the data
  257.                 r> c@ 1+ paragraph      \ calculate segments to next line
  258.                 lineptr tl:@ +          \ add to current lines segment
  259.                 incr> curline           \ bump to next line
  260.                 lineptr tl:!            \ save seg in line pointer table.
  261.                 incr> lastline ;        \ add a line to total lines
  262.  
  263. : read.openfile ( --- )                 \ read a file that is already open.
  264.                 ?<>bak
  265.                 ibfull =: iblen          \ set maximum length read buffer
  266.                 0.0 ed1hndl movepointer
  267.                 ibreset
  268.                 0 save!> loadline
  269.                 ed1hndl save!> seqhandle
  270.                 read-from dup 1- 0max =: %read-from
  271.                 1 max 1       \ skip lines till read from line
  272.                 ?do     lineread drop
  273.                 loop    off> read-from  \ reset read from counter
  274.                 off> curline
  275.                 off> lastline
  276.                 0.0 currentsize 2!
  277.                 off> rmmax
  278.                 tsegb lineptr tl:!      \ first segment setup
  279.                 tsegb #edsegs + $100 - =: tend
  280.                 lineread placeline
  281.                 begin   lineread rmsave endtst? and
  282.                 while   placeline
  283.                 repeat  drop
  284.                 restore> seqhandle
  285.                 restore> loadline ;
  286.  
  287. headerless
  288.  
  289. : .partial      ( --- )
  290.                 savecursor
  291.                 savescr
  292.                 cursor-off
  293.                 14 6 63 14 box&fill
  294.                 bcr ."     This file is \r TOO BIG \0 to fit in memory."
  295.                 bcr
  296.                 bcr ."    A partial read was performed. Press a \r KEY "
  297.                 bcr
  298.                 bcr ." \s10\1  Starting in BROWSE mode!!  \b"
  299.                 emptykbd key? if key drop then key drop
  300.                 on> ?browse
  301.                 restscr
  302.                 restcursor ;
  303.  
  304. headers
  305.  
  306. : read.oldfile ( --- )         \ get existing file
  307.                 off> newfl
  308.                 ed1hndl endfile or              \ it must have a length
  309.                 if      read.openfile           \ read it
  310.                         outbuf c@ 0<>           \ did we get it all
  311.                         if      .partial        \ if not then warn user a
  312.                         then                    \ partial read was performed
  313.                 else    true
  314.                         " File is of length ZERO." ?terror
  315.                 then    ;
  316.  
  317. headerless
  318.  
  319. : warn-prompt   ( --- )
  320.                 ." \4 NO ROOM TO SAVE \0 changes made to this file !!\b\:03"
  321.                 bcr bcr
  322.                 ." \t  You might try using Alt-W to write to another drive."
  323.                 bcr
  324.                 bcr ." \s16PRESS A KEY to acknowledge \b"
  325.                 emptykbd key? if key drop then key drop ;
  326.  
  327. : ?diskfull     ( --- f1 )
  328.                 renaming 0= ?browse or
  329.                 if      false exit
  330.                 then
  331.                 ed1hndl >nam 1+ c@ ':' =
  332.                 if  ed1hndl >nam c@ bl or 96 - else 0 then
  333.                 getdiskfree * 0 128 um/mod nip *D
  334.                 65000.  128 um/mod nip 0 d< dup
  335.                 if      savescr cursor-off
  336.                         8 4 72 16 box&fill
  337.                         bcr ." \s24\2 WARNING !! "
  338.                         bcr
  339.                         bcr
  340.                         ."   You have LESS than 65000 bytes free on disk\b\:03"
  341.                         bcr
  342.                         bcr ."   There may be " warn-prompt
  343.                         off> renaming
  344.                         off> backingup
  345.                         restscr cursor-on
  346.                 then    ;
  347.  
  348. : ?enoughdisk   ( --- f1 )      \ true if there is enough disk space to save
  349.                 ed1hndl >nam 1+ c@ ':' =
  350.                 if  ed1hndl >nam c@ bl or 96 - else 0 then
  351.                 getdiskfree * 0
  352.                 renaming 0=
  353.                 if      currentsize 2@ d+
  354.                 then    128 um/mod nip *D
  355.                 #edsegs tend toff - - 5 / 4 * 8 / 0 d< dup
  356.                                         \ * .8 / 8 to 128 bytes units
  357.                 if      savescr cursor-off
  358.                         8 4 72 14 box&fill
  359.                         bcr ." \s24\4 WARNING !! \b\:03"
  360.                         bcr
  361.                         bcr ."   There is " warn-prompt
  362.                         restscr cursor-on
  363.                 then    0= ;
  364.  
  365. headers
  366.  
  367.                                 \ n1 = edit file line number
  368.                                 \ f1 = true if error
  369. : linewrite     ( n1 --- f1 )   \ write a text line and return flag
  370.                 >lineptr tl:@ dup>r 1   \ source segment & offset
  371.                 wseg wblen              \ dest   segment & offset
  372.                 r> 0 c@l dup>r cmovel   \ length and move it
  373.                 r> +!> wblen            \ bump length
  374.                 wblen writelim >
  375.                 if      0 wblen ed2hndl wseg exhwrite wblen = dup
  376.                         if      off> wblen
  377.                         then    0=
  378.                 else    false
  379.                 then    ;
  380.  
  381. : flushwrite    ( --- f1 )      \ write the remainder of the write buffer
  382.                 wblen 0<>
  383.                 if      0 wblen ed2hndl wseg exhwrite wblen = dup
  384.                         if      off> wblen
  385.                         then    0=
  386.                 else    false
  387.                 then    ;
  388.  
  389. : write.file    ( --- )         \ write file in ed2hndl
  390.                                 \ WRITE.FILE assumes we are on FIRST line.
  391.                 ?browse ?exit   \ leave if we are in browse mode
  392.                 ed1hndl ed2hndl b/hcb cmove     \ move name to work handle
  393.                 renaming
  394.                 if      " $$$" ">$ ed2hndl $>ext        \ write to .$$$
  395.                 then
  396.                 ed2hndl hcreate                 \ create the new file
  397.                 dup " \4 Error Making File " ?softerror ?exit
  398.                 0.0 ed2hndl movepointer
  399.                 off> wblen                      \ reset write buffer
  400.                 lastline 1+ 1 max maxlines min 0
  401.                 ?do     i linewrite ?leave
  402.                 loop
  403.                 flushwrite      ( --- f1 )
  404.                 " \4 Error while writing, probably out of space " ?softerror
  405.                 ed2hndl hclose " \4 Error Closing File " ?softerror ;
  406.  
  407. headerless
  408.  
  409. 0 value escflg
  410.  
  411. : skeyfilter    ( n1 --- n2 )
  412.                 normfilter
  413.                 filtering 0= ?exit
  414. ( escape key )  dup  27 = if drop 13 on> escflg then
  415. ( Alt-F10 key)  dup 241 = if drop 13 on> escflg then
  416. (     F10 key)  dup 196 = if drop 13 on> escflg then ;
  417.  
  418. headers
  419.  
  420. : put           ( --- )         \ save a file
  421.                 write.file ;
  422.  
  423. : linebuf:      ( --- seg a1 )  \ a useful primitive
  424.                 ?cs: linebuf ;
  425.  
  426. : lineseginfo   ( --- seg a1 n1 )   \ segment of current line & length
  427.                 curline #lineseg 1 over 0 c@l ;
  428.  
  429. : showcur       ( --- )         \ display cursor at proper loc
  430.                 screenchar winoff - first.textcol +
  431.                 window.left max window.right min screenline at ;
  432.  
  433. : #lineseginfo  ( n1 --- seg a1 n2 )
  434.                 #lineseg 1 over 0 c@l ;
  435.  
  436. : stripbl's     ( --- )         \ strip off trailing blanks
  437.                 linebuf count -trailing linebuf c! drop ;
  438.  
  439. headerless
  440.  
  441. : discard.BAK   ( --- )
  442.                 ed1hndl ed2hndl $>handle
  443.                 " BAK" ">$ ed2hndl $>ext
  444.                 ed2hndl hdelete drop ;
  445.  
  446. : discard.$$$   ( --- )
  447.                 ed1hndl ed2hndl $>handle
  448.                 " $$$" ">$ ed2hndl $>ext
  449.                 ed2hndl hdelete drop ;
  450.  
  451. : norm>bak      ( --- err )     \ rename the normal filename to be .BAK
  452.                                 \ return err = error code if it failed
  453.                                 \ return err = 0 if no error
  454.                 read-write                      \ try to open it read/write
  455.                 ed1hndl hopen dup 0=            \ does original file exist?
  456.                 if      drop
  457.                         ed1hndl hclose drop     \ close it for now
  458.                         " BAK" ">$ ed2hndl $>ext \ change ED2HNDL to .BAK
  459.                         ed2hndl hdelete drop    \ delete old backup if there
  460.                         ed1hndl ed2hndl hrename \ rename original to .BAK
  461.                 then    ;                       \ exist, we don't care
  462.  
  463. : ?ferr         ( err -- err )
  464.                 dup dup
  465.                 case
  466.                         2 of    "  File does not exist "        endof
  467.                         3 of    "  No Path found "              endof
  468.                         5 of    "  File is READ ONLY "          endof
  469.                                 "  Unknown file error "
  470.                         drop
  471.                 endcase ?softerror ;
  472.  
  473. : recover.$$$   ( --- err )             \ return false if all is OK!
  474.                                         \ else return code for error
  475.                 renaming dup 0= ?exit drop
  476.                 ed1hndl ed2hndl $>handle
  477.                 " $$$" ">$ ed2hndl $>ext
  478.                 ed2hndl hopen dup 0= swap ?exit drop
  479.                                                 \ leave if .$$$ doesn't exist?
  480.                 ed2hndl hclose drop             \ close it for now
  481.                 norm>bak dup 0=                 \ no error,
  482.                 over 2 = or                     \ or file doen't exist
  483.                 if      drop                    \ then rename $$$ to norm
  484.                         " $$$" ">$ ed2hndl $>ext \ change ED2HNDL to .$$$
  485.                         ed2hndl ed1hndl hrename \ rename .$$$ to original
  486.                 then    ;
  487.  
  488. headers
  489.  
  490. : getline       ( --- )         \ get current line to linebuf.
  491.                 linebuf linebuf.len blank
  492.                 lineseginfo >r
  493.                 linebuf: 1+ r@ ch/l 2+ min cmovel  ( --- )
  494.                 r@ 2- =: linelen
  495.                 r> linebuf + 1- dup @ crlfval =
  496.                 if      blbl swap !
  497.                 else    drop  2 +!> linelen
  498.                 then    ch/l linebuf c! off> lchng ;
  499.  
  500. : putline       ( --- )
  501.                 lchng 0= ?exit          \ only save if changed
  502.                 stripbl's               \ restore linebuf to file
  503.                 crlfval linebuf count + !
  504.                 2 linebuf c+!
  505.                 lineptr tl:@ 0 c@l      \ Get OLD line length
  506.                 linebuf c@ - negate     \ NEW length from OLD = Difference
  507.                 s>d currentsize D+!     \ adjust file size for NEW line
  508.                 linebuf:                \ source in line buffer
  509.                 lineptr dup tl+ tl:@    \ next line segment
  510.                 linebuf c@ 1+ paragraph - \ minus segment for current line
  511.                 dup rot tl:!            \ seg current line segment
  512.                 dup =: tend             \ set TEND
  513.                 0 linebuf c@ 1+ cmovel ; \ move the data into text segment
  514.  
  515. \ MUST HAVE AT LEAST 1600 BYTES BETWEEN TOFF AND TEND FOR THIS TO WORK
  516.  
  517. \ Backwards segment move.  If you think this is easy your kidding yourself!
  518.  
  519. : cmove-segs>   ( starg-seg destination-seg length-segs --- )
  520.                 dup>r dup d+            \ adjust to end for backwards move
  521.                 r>
  522.                 0 100 um/mod            \ calculate blocks of 100 segments
  523.                 >r                      \ save main move blocks
  524.                                         \ move remainder first
  525.                 dup>r dup d-            \ adj from end back by remainder
  526.                 2dup 0 tuck r> 16 * cmovel
  527.                 r> 0
  528.                 ?do     100 100 d-      \ adjust for this move
  529.                         2dup 0 tuck     \ setup as seg-off seg-off
  530.                         1600 cmovel     \ move 1.6k bytes
  531.                 loop    2drop ;
  532.  
  533. : cmove-segs    ( starg-seg destination-seg length-segs --- )
  534.                 0 1000 um/mod           \ calculate blocks of 1000 segments
  535.                 swap >r                 \ save the remainder for later
  536.                 0
  537.                 ?do     2dup 0 tuck     \ setup as seg-off seg-off
  538.                         16000 cmovel    \ move 16k bytes
  539.                         1000 1000 d+    \ adj for next move
  540.                 loop    0 tuck          \ prepare for final move
  541.                 r> 16 * cmovel ;        \ move remainder of data
  542.  
  543. : toline-       ( n1 --- )
  544.                 0MAX
  545.                 curline over <= if drop exit then
  546.                 dup>r #lineseg                  \ source line segment
  547.                 toff over - >r                  \ amount moved is saved
  548.                 tend r@ -                       \ destination line segment
  549.                 2dup - negate r@ swap >r        \ save distance moved
  550.                 cmove-segs>                     \ move the segments
  551.                 r> curline r> r@ swap >r
  552.                 adj_ptr_lines                   \ adjust the line ptr tbl
  553.                 r> negate dup +!> toff +!> tend
  554.                 r> =: curline ;
  555.  
  556. : toline+       ( n1 --- )
  557.                 lastline min
  558.                 curline over >= if drop exit then
  559.                 >r
  560.                 curline  #lineseg               \ start segment
  561.                 r@ #lineseg over - >r           \ amount moved is saved
  562.                 toff                            \ destination segment
  563.                 2dup - negate r@ swap >r        \ save distance moved
  564.                 cmove-segs                      \ move the segments
  565.                 r> r> r@ swap >r curline
  566.                 adj_ptr_lines                   \ adjust the line ptr tbl
  567.                 r> dup +!> toff +!> tend
  568.                 r> =: curline ;
  569.  
  570. : curline+      ( --- )         \ move down one line in text
  571.                 curline lastline = ?exit
  572.                 lineseginfo 1+ >r 1- toff 0 r@ cmovel
  573.                 toff lineptr tl:! r> paragraph +!> toff
  574.                 incr> curline lineptr tl:@ =: tend ;
  575.  
  576. : curline-      ( --- )         \ move up one line in text
  577.                 curline 0= ?exit
  578.                 curline 1- >lineptr tl:@ dup 0 c@l 1+ >r 0
  579.                 lineptr tl:@ r@ paragraph - 0 r@ cmovel
  580.                 r@ paragraph negate +!> toff
  581.                 lineptr dup tl:@ r> paragraph - swap tl- tl:!
  582.                 decr> curline lineptr tl:@ =: tend ;
  583.  
  584.                 \ conditional lastline and firstline tests
  585.  
  586. : ?lastline     ( --- f1 ) curline lastline >= ;
  587.  
  588. : ?firstline    ( --- f1 ) curline 1 < ;
  589.  
  590. headerless
  591.  
  592. : sinit         ( --- ) \ initialize file, and linelist table
  593.                 off> changed
  594.                 on> imode
  595.                 on> markstrt
  596.                 on> markend
  597.         \ setup tend to point to lst possible segment in 64k block
  598.                 tsegb #edsegs + =: tend
  599.                 lastline 1- >lineptr tl:@ dup 0 c@l paragraph + =: toff
  600.         \ set line beyond last actual line to just beyond end of buffer
  601.                 tsegb #edsegs + lastline >lineptr tl:!
  602.                 lastline =: curline
  603.                 0 toline-               \ go back to first line
  604.                 decr> lastline
  605.                 off> updated off> lookflg
  606.                 off> curline off> lmrgn
  607.                 first.textline =: screenline
  608.                 off> curline getline ;
  609.  
  610. : pagechar      ( --- )
  611.                 last.textcol ( 1- ) !> #out  ?DOSIO
  612.                 if      @> #out @> #line at
  613.                 then    ." \r" ;
  614.  
  615. code ?page-char ( n1 --- )
  616.                 pop ax
  617.                 sub dx, dx
  618.                 mov bx, # prtlines
  619.                 div bx
  620.                 cmp dx, # 0
  621.              0= if      mov ax, # ' pagechar
  622.                         jmp ax
  623.                 then
  624.                 next    end-code
  625.  
  626. headers
  627.  
  628. : sltype        ( n1 --- ) \ n1 is data line
  629.                 ?DOSIO
  630.                 if      @> #out @> #line at
  631.                         (key?) if drop exit then
  632.                 then    >norm
  633.                 marking
  634.                 if      dup markstrt markend between
  635.                         if >rev then
  636.                 then
  637.                 on> nosetcur
  638.                 #lineseginfo 2- clipline typeL
  639.                 edeeol off> nosetcur ;
  640.  
  641. headerless
  642.  
  643. 0 value lincol          \ column of linenumber in status line
  644.  
  645. : doborder      ( --- )
  646.                 window.right cols <
  647.                 if      .g'| window.left   last.textline 1+ at .g|.
  648.                 else         first.textcol last.textline 1+ at
  649.                 then
  650.                 ed1hndl count dup 8 +
  651.                 text.width 2- swap - 2 /
  652.                 1- >norm -s
  653.                 >attrib1 ."  File = " type space >norm
  654.                 window.right cols 1- min #out @ - 0MAX -s
  655.                 ?DOSIO 0=                       \ no lower right corner with
  656.                 window.right cols < and         \ DOS I/O
  657.                 if .g.| then
  658.                 window.left 2+ last.textline 1+ at
  659.                 ." \4 HELP=F1 "
  660.                 window.right 11 - last.textline 1+ at
  661.                 ." \4 MENU=ESC "
  662.                 window.right cols <
  663.                 if      last.textline 1+ first.textline
  664.                         ?do     ( last.textcol )
  665.                                 window.right i at .g|
  666.                                 window.left  i at .g|
  667.                         loop
  668.                         mouseflg
  669.                         if      >attrib4
  670.                                 window.right first.textline at          ." "
  671.                                 window.left first.textline  at          ." "
  672.                                 window.right 13 - last.textline 1+ at   ." "
  673.                                 window.right last.textline 4 - at       ." U"
  674.                                 window.right last.textline 3 - at       ." P"
  675.                                 window.right last.textline 1 - at       ." D"
  676.                                 window.right last.textline     at       ." N"
  677.                                 >norm
  678.                         then
  679.                 then    off> ?border ;
  680.  
  681. : <statfunc>    ( --- ) \ show file status to user
  682.                 >attrib1
  683.                 ."  Line="       @> #out =: lincol
  684.                                  curline %read-from +  1+ 5 .l
  685.                 ." Column="      screenchar            1+ 3 .l
  686.                 ."  Page#="      curline prtlines /    1+ 3 .l
  687.                 ."  Lines="      lastline %read-from + 1+ 4 .l
  688.                 ."  Characters=" currentsize 2@        1   d.r
  689.                 >norm window.right @> #out - 0MAX -s
  690.                 ?border
  691.                 if      doborder
  692.                 then    ;
  693.  
  694. : fullfunc      ( --- ) \ status for when file is full > 64k
  695.                 window.left dup 0MAX statusline at >norm 0>=
  696.                 if      .g|'
  697.                 then    2 -s ." \5MEM FULL" <statfunc> ;
  698.  
  699. : statfunc      ( --- )
  700.                 window.left dup 0MAX statusline at >norm 0>=
  701.                 if      .g|'
  702.                 then    2 -s
  703.                 marking markdone 0= and
  704.                 if
  705. ." \2 MARKING TEXT \r  Use up and down arrow to select lines of text.  \2 F3=Done "
  706.                         2 -s
  707.                 else    ?browse
  708.                         if              ." \4 BROWSE "
  709.                         else    imode
  710.                                 if      ." \4 INSERT "
  711.                                 else    ." \1OVERTYPE"
  712.                                 then
  713.                         then    <statfunc>
  714.                         mouseflg
  715.                         if      71 statusline at ." \4\0─"
  716.                         else    73 statusline at
  717.                         then    >attrib4
  718.                         browselevel 0>
  719.                         if      ."  +"
  720.                                 browselevel 3 .l
  721.                         else    ."  F10 "
  722.                         then
  723.                 then    >norm ;
  724.  
  725. ' statfunc is showstat
  726.  
  727. headers
  728.  
  729. : ?full         ( --- f1 )      \ is memory full?
  730.                 tend toff - $100 < ;     \ need more than $100 = 1600 decimal
  731.  
  732. : ?showfull     ( --- f1 )      \ set status func for memory
  733.                 ?full dup       \ condition
  734.                 if      ['] fullfunc is showstat
  735.                 else    ['] statfunc is showstat
  736.                 then    ;
  737.  
  738. : ?maxlines     ( --- f1 )
  739.                 lastline 4 + maxlines > ;
  740.  
  741. : ?left/right   ( --- )
  742.                 screenchar text.width 1- -      \ winoff must be at least
  743.                 winoff max                      \ but not less than now
  744.                 =: winoff                       \ new value
  745.                 screenchar winoff <             \ left edge check
  746.                 if      screenchar =: winoff
  747.                 then    ;
  748.  
  749. : sdisp         ( --- )
  750.                 first.textcol screenline at on> nosetcur
  751.                 marking
  752.                 if      curline markstrt markend between
  753.                         if >rev then
  754.                 then
  755.                 ?CS: linebuf 1+ linelen clipline typeL edeeol
  756.                 curline ?page-char off> nosetcur >norm ;
  757.  
  758. : scrshow       ( --- )         \ display screen full of file.
  759.                 cursor-off
  760.                 ?left/right
  761.                 first.textline curline screenline
  762.                 first.textline - -
  763.                 0MAX dup last.textline 1+ first.textline - + swap
  764.                 do      i curline =     >norm
  765.                         if      sdisp
  766.                         else    dup !> #line first.textcol =: #out
  767.                                 i lastline <=
  768.                                 if      i sltype
  769.                                 else    end-eeol
  770.                                 then    i ?page-char
  771.                         then    1+
  772.                 loop    drop >norm cursor-on ;
  773.  
  774. : <sdln>        ( --- ) putline curline+ getline ;
  775.  
  776. : <suln>        ( --- ) putline curline- getline ;
  777.  
  778. : sdisplay      ( --- )         \ display current screen line.
  779.                 cursor-off sdisp cursor-on ;
  780.  
  781. headerless
  782.  
  783. : ins.linelist  ( --- )                 \ add new entry to line pointer list.
  784.                 lineptr tl: dup tl+ tl:
  785.                 maxlines curline - 2- 2* cmovel>
  786.                 incr> lastline
  787.                 lineptr dup tl+ tl:@    \ next line segment
  788.                 1-                      \ minus segment for current line
  789.                 dup rot tl:!            \ seg current line segment
  790.                 =: tend                 \ set TEND
  791.                 lineptr tl:@
  792.                 2 over 0 c!l            \ set length to 0
  793.                 crlfval swap 1 !l       \ put in CRLF
  794.                 0.2 currentsize D+!     \ Adjust file size
  795.                 ;
  796.  
  797. : ?appendline   ( --- )
  798.                 ?lastline
  799.                 if      lineptr tl:@ dup>r 0    \ from  seg offset
  800.                         r@ 1- 0                 \ to    seg offset
  801.                         tsegb #edsegs + r> -    \ length in segments
  802.                         16 *                    \ convert to bytes
  803.                         cmovel                  \ move the data
  804.                         lineptr tl:@ 1-         \ correct line pointer value
  805.                         lineptr tl:!            \ save into line table
  806.                         tsegb #edsegs + 1-
  807.                         lineptr tl+ tl:!        \ new last = 1 before end
  808.                         lineptr tl+ tl:@        \ segment of NEW last line
  809.                            2 over 0 c!l         \ set count 2
  810.                         crlfval swap 1 !l       \ put in CRLF
  811.                         tsegb #edsegs +         \ get the last segment
  812.                         lineptr tl+ tl+ tl:!    \ save in lastline + 1
  813.                         incr> lastline          \ one more line
  814.                         0.2 currentsize D+!     \ adjust length
  815.                 then    ;
  816.  
  817. headers
  818.  
  819. : clipdown      ( --- )
  820.                 screenline >r
  821.                 last.textline lastline curline - 0MAX -
  822.                 screenline max last.textline min
  823.                 curline first.textline + min
  824.                 dup =: screenline r> <>
  825.                 if      scrshow then    ;
  826.  
  827. defer ?mark-plus        ' noop is ?mark-plus
  828.  
  829. : sdln          ( --- )         \ sequential line down
  830.                 ?lastline ?exit
  831.                 <sdln> incr> screenline
  832.                 ?mark-plus clipdown ;
  833.  
  834. : <shom>        ( --- )         \ home to beginning of file
  835.                 putline 0 toline-
  836.                 first.textline =: screenline
  837.                 getline ;
  838.  
  839. : shom          ( --- )
  840.                 <shom>
  841.                 off> screenchar
  842.                 off> lmrgn
  843.                 scrshow ;
  844.  
  845. : suln         ( --- )         \ sequential line up
  846.                 ?firstline if exit then
  847.                 <suln> decr> screenline
  848.                 ?mark-plus screenline >r
  849.                 screenline first.textline - curline min
  850.                 0MAX first.textline + dup =: screenline r> <>
  851.                 if      scrshow
  852.                 then    ;
  853.  
  854. headerless
  855.  
  856. : ?cursor       ( --- )
  857.                 imode if ins-cursor else norm-cursor then ;
  858.  
  859. : line>ldel.buf ( --- )
  860.                 dseg
  861.                 if      dseg ldel.buf 2dup mxlln +
  862.                         ldel.cnt maxdline 1- min mxlln * cmovel>
  863.                         ldel.cnt 1+ maxdline 1- min =: ldel.cnt
  864.                         linelen linebuf c! ?cs: linebuf dseg ldel.buf
  865.                         linelen 1+ mxlln min cmovel
  866.                 then    ;
  867.  
  868. : ldel>linebuf  ( --- )
  869.                 dseg
  870.                 if      dseg ldel.buf 2dup c@l
  871.                         ?cs: linebuf rot 1+ cmovel
  872.                         linebuf c@ =: linelen
  873.                         dseg ldel.buf 2dup mxlln + 2swap
  874.                         ldel.cnt maxdline min dup 1- =: ldel.cnt
  875.                         mxlln * cmovel
  876.                 then    ;
  877.  
  878. headers
  879.  
  880. : #deletelines  ( n1 --- )
  881.                 0MAX ?dup 0= ?exit
  882.                 >r curline r@ lastline min bounds
  883.                 ?do     i >lineptr tl:@ 0 c@l negate -1 currentsize D+!
  884.                 loop
  885.                 r@ tl* tl:@ =: tend
  886.                 lineptr tl: dup r@ tl* + tl: 2swap
  887.                 maxlines >lineptr lineptr r@ tl* + - cmovel
  888.                 r> negate +!> lastline
  889.                 getline modified ;
  890.  
  891. : linedelete    ( --- )
  892.                 ?lastline       \ if we are on the last line, then
  893.                                  \ just clear the line don't delete it.
  894.                 if      lineptr tl:@ 0 c@l negate s>d currentsize D+!
  895.                         2 s>d currentsize D+!
  896.                         tsegb #edsegs + 1- dup lineptr tl:! =: tend
  897.                            2 curline #lineseg 0 c!l   \ install count of 2
  898.                         crlfval curline #lineseg 1 !l \ containing only CRLF
  899.                 else    lineptr tl:@ 0 c@l negate s>d currentsize D+!
  900.                         lineptr dup tl+ tl:@ =: tend
  901.                         maxlines >lineptr over - >r
  902.                         tl: dup tl+ tl: 2swap r> cmovel
  903.                         decr> lastline
  904.                 then    getline modified ;
  905.  
  906. : <ldel>        ( --- )         \ delete the current line.
  907.                 line>ldel.buf linedelete ?showfull drop ;
  908.  
  909. : ldel          ( --- )
  910.                 ?browse ?exit
  911.                 <ldel> scrshow ;
  912.  
  913. : to.line       ( n1 --- )
  914.                 toline+ getline ;
  915.  
  916. : backto.line   ( n1 --- )
  917.                 toline- getline ;
  918.  
  919. : .elapse       ( --- )
  920.                 ." Edit time " time-elapsed b>t
  921.                 ttime 2@ form-time count type ;
  922.  
  923. : updt          ( --- )         \ save changes if any to disk.
  924.                 ?browse ?exit
  925.                 savescr
  926.                 cursor-off
  927.                 changed 0=
  928.                 if      8 6 70 10 box&fill
  929.                         bcr ."  \2 NO CHANGES to save in "
  930.                         >attrib2 .ed1hndl >norm 5 tenths
  931.                 else
  932.                         save> screenline
  933.                         curline >r
  934.                         8 7 70 9 box&fill
  935.                         ."  \2 Saving Changes to "
  936.                         >attrib2 .ed1hndl >norm
  937.                         <shom>
  938.                         discard.bak
  939.                         ?enoughdisk
  940.                         if      put off> changed on> updated
  941.                         else    showstat
  942.                         then
  943.                         r> to.line
  944.                         restore> screenline
  945.                 then    5 tenths scrshow ?cursor emptykbd off> fdbuf
  946.                 restscr cursor-on showcur ;
  947.  
  948. defer try_to_open       ' noop is try_to_open
  949.  
  950. : ?newopen      ( -- )
  951.                 ?eddone                 \ if ?eddone true
  952.                 hdepth 1 < and          \ and handle depth = 0
  953.                 leavesave 0= and        \ and leavesave is false
  954.                 leavenow 0= and         \ and doleave is false
  955.                 if      savescr
  956.                         18 15 62 18 box&fill
  957.                         ."  \1 Type in the name of a file to edit, or " bcr
  958.                         ."     \1 press \2 ESC \1 to leave the editor. "
  959.                         try_to_open
  960.                         restscr
  961.                         leavesave negate =: leavesave
  962.                                         \ convert -1 to 1 to make <RED>
  963.                                         \ not save where we are leaving from
  964.                 then    ;
  965.  
  966. : squt          ( c1 --- c1 )   \ discard changes and exit
  967.                 ?shiftkey >r
  968.                 off> loadline
  969.                 off> screenchar
  970.                 discard.$$$
  971.                 on> ?eddone
  972.                 off> edready
  973.                 r> 0=
  974.                 if      ?newopen
  975.                 else    on> pop-extra
  976.                 then    0 rows 1- at
  977.                 off> lmrgn ;
  978.  
  979. : sesc          ( c1 --- c1 )   \ save changes and exit
  980.                 curline 1+ =: loadline
  981.                 <shom>
  982.                 cursor-off
  983.                 changed
  984.                 if      savescr
  985.                         6 6 74 10 box&fill bcr
  986.                         ."  Saving Changes to " .ed1hndl bcr
  987.                         ?enoughdisk
  988.                         if      discard.bak
  989.                                 put
  990.                                 recover.$$$ ?ferr 0=
  991.                                 if      on> ?eddone
  992.                                         off> changed
  993.                                         7 tenths
  994.                                 then    restscr
  995.                                 ?newopen
  996.                         else    restscr scrshow showstat
  997.                         then
  998.                 else    savescr
  999.                         true    updated
  1000.                         if      drop recover.$$$ ?ferr 0=
  1001.                         then
  1002.                         if      on> ?eddone
  1003.                                 off> changed
  1004.                                 restscr
  1005.                                 ?newopen
  1006.                         else    restscr scrshow showstat
  1007.                         then
  1008.                 then    0 rows 1- at
  1009.                 off> lmrgn cursor-on ;
  1010.  
  1011. headerless
  1012.  
  1013. defer <nlnx>    ' noop is <nlnx>
  1014.  
  1015.                 \ conditionally add a line
  1016. : ?addline      ( --- )
  1017.                 ?lastline
  1018.                 if      screenchar ch/l =: screenchar
  1019.                         <nlnx> =: screenchar
  1020.                 then    ;
  1021.  
  1022. headers
  1023.  
  1024. : ?rightshow    ( --- )
  1025.                 winoff
  1026.                 screenchar text.width 1- -      \ winoff must be at least
  1027.                 winoff max                      \ but not less than now
  1028.                 dup =: winoff                   \ new value
  1029.                 <>                              \ if new not equal old
  1030.                 if      scrshow                 \ then update screen
  1031.                 then    ;
  1032.  
  1033. : rchr          ( --- )         \ right a character
  1034.                 screenchar 1+ ch/l 1- min dup =: screenchar
  1035.                 132 >=                  \ limit to column 132
  1036.                 if      off> screenchar ?addline sdln scrshow
  1037.                 then    ?rightshow ;
  1038.  
  1039. : chrptr        ( --- a1 )      \ cur character line pointer
  1040.                 screenchar linebuf 1+ + ;
  1041.  
  1042.                                 \ goto beginning of curent line
  1043. : shoml         ( --- )
  1044.                 off> screenchar
  1045.                 off> lmrgn
  1046.                 off> winoff
  1047.                 scrshow ;
  1048.  
  1049. : sendl         ( --- )         \ goto end of current line
  1050.                 stripbl's linebuf c@ =: linelen
  1051.                 ch/l linebuf c!
  1052.                 linelen =: screenchar
  1053.                 ?rightshow ;
  1054.  
  1055. : send          ( --- )         \ goto end of file
  1056.                 putline lastline toline+
  1057.                 last.textline curline 1+ min =: screenline
  1058.                 getline sendl scrshow ;
  1059.  
  1060. : ?leftshow     ( --- )         \ reshow screen of screen scrolled
  1061.                 screenchar winoff <
  1062.                 if      screenchar =: winoff
  1063.                         scrshow
  1064.                 then    ;
  1065.  
  1066. : lchr          ( --- )         \ left a character
  1067.                 -1 +!> screenchar screenchar 0<
  1068.                 if      off> screenchar suln sendl scrshow
  1069.                 else    ?leftshow
  1070.                 then    ;
  1071.  
  1072.   10 value autosave-minutes
  1073. true value autosaving?
  1074.  
  1075. headerless
  1076.  
  1077. 0 value keycnt
  1078. 0 value not-saved?
  1079. 2variable savetime
  1080.  
  1081. : autosave      ( --- )
  1082.                 ?browse ?exit
  1083.                 autosaving? 0= ?exit
  1084.                 keycnt 1000 >
  1085.                 if      not-saved?
  1086.                         if      gettime t>b savetime 2!
  1087.                                 off> not-saved?
  1088.                         else    off> keycnt
  1089.                                                 \ 60k = 10 minutes
  1090.                                 gettime t>b savetime 2@ d-
  1091.                                 autosave-minutes 6000 *d d>
  1092.                                 changed and
  1093.                                 if      off> not-saved?
  1094.                                         updt showcur
  1095.                                 then
  1096.                         then
  1097.                 else    incr> keycnt
  1098.                 then    ;
  1099.  
  1100. : ?showstatus   ( --- )
  1101.                 normbgstuff
  1102.                 autosave
  1103.                 vstaton 0= ?exit
  1104.                 statcnt 40 >
  1105.                 if      off> statcnt off> vstaton
  1106.                         @> #out @> #line showstat at ?cursor
  1107.                 then    incr> statcnt ;
  1108.  
  1109. : statkey       ( --- c1 )
  1110.                 normkey
  1111.                 off> keycnt
  1112.                 on> not-saved?
  1113.                 off> statcnt ;
  1114.  
  1115. headers
  1116.  
  1117. : pdn           ( --- )         \ go down a page in file
  1118.                 ?lastline if exit then
  1119.                 putline getline
  1120.                 last.textline 1+ first.textline - 2-
  1121.                 3 screenline - +
  1122.                 1 max 0
  1123.                ?do      putline curline+ getline
  1124.                         ?lastline
  1125.                         if      last.textline =: screenline leave then
  1126.                 loop    3 last.textline min =: screenline
  1127.                 ?mark-plus clipdown scrshow emptykbd ;
  1128.  
  1129. : pup           ( --- )         \ go up a page in file
  1130.                 ?firstline if exit then
  1131.                 putline getline
  1132.                 last.textline 1+ first.textline - 2-
  1133.                 screenline 3 - +
  1134.                 1 max 0
  1135.                ?do      putline curline- getline
  1136.                         ?firstline
  1137.                         if      first.textline =: screenline leave then
  1138.                 loop    3  first.textline curline + min =: screenline
  1139.                 ?mark-plus scrshow emptykbd ;
  1140.  
  1141. headerless
  1142.  
  1143. : >space        ( --- )         \ move to next space in line
  1144.                 linelen dup screenchar over min
  1145.                 ?do     linebuf 1+ i + c@ dup bl =
  1146.                         swap 127 > or
  1147.                         if      drop i leave then
  1148.                 loop    =: screenchar   ;
  1149.  
  1150. : space>        ( --- )         \ move to non blank in line
  1151.                 linelen dup screenchar over min
  1152.                 ?do     linebuf 1+ i + c@ dup bl <>
  1153.                         swap 127 > 0= and
  1154.                         if      drop i leave then
  1155.                 loop    linelen min =: screenchar ;
  1156.  
  1157. : <<space>      ( ---  n1 )     \ n1 = offset from line strt to prev space
  1158.                 0 dup screenchar
  1159.                 ?do     linebuf 1+ i + c@ dup bl =
  1160.                         swap 127 > or
  1161.                         if      drop i leave then
  1162.             -1 +loop    dup =: screenchar ;
  1163.  
  1164. : <text         ( --- )      \ move to previous text in line.
  1165.                 0 dup screenchar
  1166.                 ?do     linebuf 1+ i + c@ dup bl <>
  1167.                         swap 127 > 0= and
  1168.                         if      drop i leave then
  1169.             -1 +loop    =: screenchar ;
  1170.  
  1171. headers
  1172.  
  1173. : %scrllft      ( n1 --- )
  1174.                 winoff 0>
  1175.                 if      winoff over - 0MAX =: winoff
  1176.                         winoff text.width 1- + screenchar min =: screenchar
  1177.                         scrshow
  1178.                 then    drop ;
  1179.  
  1180. : scrllft       ( --- )
  1181.                 4 %scrllft ;
  1182.  
  1183. : %scrlrt       ( n1 --- )
  1184.                 winoff text.width + 252 <
  1185.                 if      dup +!> winoff
  1186.                         winoff screenchar max =: screenchar
  1187.                         scrshow
  1188.                 then    drop ;
  1189.  
  1190. : scrlrt        ( --- )
  1191.                 4 %scrlrt ;
  1192.  
  1193. : rwrd          ( --- )
  1194.                 ?shiftkey if scrlrt  exit then
  1195.                 screenchar linelen @> rmargin min =
  1196.                 ?lastline 0= and
  1197.                 if      off> screenchar sdln scrshow exit
  1198.                 then    >space
  1199.                 screenchar linelen >=
  1200.                 if      scrshow exit then
  1201.                 space> scrshow ;
  1202.  
  1203. : lwrd          ( --- )         \ go back to previous word.
  1204.                 ?shiftkey if scrllft  exit then
  1205.                 screenchar 0= ?firstline   0= and
  1206.                 if      suln linelen =: screenchar scrshow exit
  1207.                 then    screenchar 1- 0MAX =: screenchar
  1208.                 <text   screenchar 0=
  1209.                 if      scrshow exit
  1210.                 then    <<space>
  1211.                 if      incr> screenchar
  1212.                 then    @> rmargin screenchar min =: screenchar scrshow ;
  1213.  
  1214. headerless
  1215.  
  1216. : splitline     ( --- )
  1217.                 linebuf screenchar + 1+ dup split.buf 1+
  1218.                 linelen screenchar - 1+ 0MAX dup>r cmove
  1219.                 r> split.buf c! ch/l screenchar - blank
  1220.                 screenchar =: linelen
  1221.                 ?appendline modified <sdln>
  1222.                 linebuf linebuf.len blank
  1223.                 split.buf count linebuf 1+ lmrgn + swap cmove
  1224.                 split.buf c@ lmrgn + dup linebuf c! =: linelen
  1225.                 ins.linelist modified <suln> ;
  1226.  
  1227. : <nln>         ( --- ) \ inserts line if in insert mode.
  1228.                 ?showfull ?maxlines or
  1229.                 if beep exit then
  1230.                 imode
  1231.                 if      splitline
  1232.                 else    ?lastline
  1233.                         if      stripbl's linebuf c@ =: screenchar
  1234.                                 SplitLine
  1235.                         then
  1236.                 then    on> changed ;
  1237.  
  1238. ' <nln> is <nlnx>
  1239.  
  1240. headers
  1241.  
  1242. : nln           ( f1 --- f1 )   \ next line function
  1243.                                 \ inserts line if in insert mode.
  1244.                 ?browse
  1245.                 if      sdln
  1246.                 else    <nln>   sdln
  1247.                         lmrgn             =: screenchar
  1248.                         lmrgn linelen max =: linelen
  1249.                         ch/l linebuf c!
  1250.                 then    scrshow ;
  1251.  
  1252. : nodisp-nln    ( --- ) \ next line function
  1253.                         \ inserts line if in insert mode.
  1254.                 <nln>   <sdln> off> screenchar ch/l linebuf c! ;
  1255.  
  1256. headerless
  1257.  
  1258. : csaveon       on> csaveflg ;
  1259.  
  1260. : csaveoff      off> csaveflg ;
  1261.  
  1262. : csave         ( c1 --- )
  1263.                 csaveflg
  1264.                 if      fdbuf c@ 64  >
  1265.                         if      fdbuf count >r dup 1+ swap r> cmove
  1266.                                 fdbuf c@ 1- 0MAX fdbuf c!
  1267.                         then    fdbuf count + c! fdbuf c@ 1+ fdbuf c!
  1268.                 else    drop
  1269.                 then    ;
  1270.  
  1271. headers
  1272.  
  1273. : <fdel>        ( --- )
  1274.                 screenchar dup linebuf + 1+ dup c@ csave
  1275.                 dup 1+ swap rot ch/l 1+ swap - cmove
  1276.                 modified ?showfull drop decr> linelen ;
  1277.  
  1278. headerless
  1279.  
  1280. : ?lmargin      ( --- )
  1281.                 screenchar 0=
  1282.                 if      lmrgn =: screenchar then ;
  1283.  
  1284. : ?right        ( --- )
  1285.                 wrapped
  1286.                 if      screenchar wraploc 1- <
  1287.                         if      rchr ?lmargin
  1288.                         else    screenchar wraploc -
  1289.                                 lmrgn + 1+ =: screenchar
  1290.                                 sdln
  1291.                         then    scrshow
  1292.                 else    rchr    ?lmargin
  1293.                 then    ;
  1294.  
  1295. : del<>bl's     ( --- )         \ delete non blanks
  1296.                 begin   chrptr c@ bl <>
  1297.                 while   <fdel>
  1298.                 repeat  ;
  1299.  
  1300. : delbl's       ( --- )         \ delete blanks
  1301.                 ch/l screenchar
  1302.                 ?do      chrptr c@ bl <> ?leave <fdel>
  1303.                 loop    ;
  1304.  
  1305. : AppendLine    ( --- )         \ append this line to previous.
  1306.                 ?firstline if beep exit then
  1307.                 imode
  1308.         if      stripbl's split.buf linebuf.len blank
  1309.                 linebuf split.buf over c@ dup>r 1+ cmove
  1310.                 curline 1- #lineseg 0 c@l r> + ch/l 1- >
  1311.                 if      beep getline off> screenchar
  1312.                 else    ldel suln stripbl's
  1313.                         split.buf count linebuf count dup if 1+ then
  1314.                         dup>r + swap cmove  modified split.buf c@ r@ +
  1315.                         ch/l 10 - min dup 10 + linebuf c! =: linelen
  1316.                         r> @> rmargin 1- min =: screenchar putline
  1317.                         screenchar linelen 1- min 0MAX =: screenchar
  1318.                 then
  1319.         else    suln stripbl's linebuf c@ =: screenchar
  1320.         then    getline sdisplay ;
  1321.  
  1322. headers
  1323.  
  1324. : bdel          ( --- )         \ back delete
  1325.                 ?browse
  1326.         if      suln sendl
  1327.         else    screenchar 0=
  1328.                 if      AppendLine scrshow
  1329.                 else    imode
  1330.                         if      screenchar dup linebuf + 1+ dup 1-
  1331.                                 rot ch/l 1+ swap - cmove
  1332.                                 decr> screenchar
  1333.                                 linelen 1- screenchar max linelen min
  1334.                                 =: linelen
  1335.                         else    decr> screenchar
  1336.                                 bl chrptr c! modified putline getline
  1337.                         then    sdisplay screenchar lmrgn min =: lmrgn
  1338.                 then    modified
  1339.                 ?showfull drop ?leftshow
  1340.         then    ;
  1341.  
  1342. defer ?wrap     ' noop is ?wrap
  1343.  
  1344. : schr          ( c1 --- )    \ insert sequential char in line.
  1345.                 ?browse   if drop exit then
  1346.                 ?showfull ?exit
  1347.                 screenchar linelen max =: linelen
  1348.                 imode
  1349.         if      screenchar linebuf 1+ + dup 1+
  1350.                 linelen screenchar - 0MAX cmove> incr> linelen
  1351.         then    dup screenchar linebuf 1+ + c!  bl <>
  1352.                 if      linelen screenchar 1+ max =: linelen
  1353.                 then    sdisplay modified
  1354.                 ?wrap   ?right  ;
  1355.  
  1356. : wudel         ( --- )
  1357.                 ?browse ?exit
  1358.                 true save!> imode
  1359.                 fdbuf count bounds
  1360.                 ?do     fdbuf 1+ c@ >r                  \ get char
  1361.                         fdbuf 2+ fdbuf 1+               \ source destination
  1362.                         fdbuf c@ 1- 0MAX cmove         \ clip char out
  1363.                         fdbuf c@ 1- 0MAX fdbuf c!      \ reduce count
  1364.                         r> ?dup 0= ?leave               \ leave if null
  1365.                         schr                            \ insert it
  1366.                 loop    restore> imode ;
  1367.  
  1368. : @word@cur     ( -- a1 )
  1369.                 save> screenchar        \ save current cursor position
  1370.                 <<space>                \ if space found, then bump forward 1
  1371.                 linebuf 1+ + c@
  1372.                 dup bl =                \ did we find a space,
  1373.                 swap hyperchar = or     \ or the hyper character?
  1374.                 if      incr> screenchar
  1375.                 then
  1376.                 screenchar              \ cursor position
  1377.                 >space                  \ find next space
  1378.                 screenchar              \ get new cursor position ( old new )
  1379.                 swap =: screenchar      \ restore cursor position ( new )
  1380.                 screenchar - 0max >r    \ length of word under cursor saved
  1381.                 linebuf 1+ screenchar + \ source
  1382.                 r> here c!
  1383.                 here count cmove
  1384.                 restore> screenchar
  1385.                 here ;
  1386.  
  1387. headerless
  1388.  
  1389. : .nofound      ( --- )
  1390.                 savecursor
  1391.                 savescr
  1392.                 cursor-off
  1393.                 20 3 60 5 box&fill
  1394.                 ."  No text has been found.."
  1395.                 1 seconds
  1396.                 restscr
  1397.                 restcursor ;
  1398.  
  1399. : #linelook     ( n1 --- f1 )   \ look through line n1
  1400.                 >r slook.buf count r> #lineseg =: sseg
  1401.                 1 @> sseg 0 c@l
  1402.                 screenchar - 0MAX swap screenchar + swap
  1403.                 search tuck
  1404.                 if      +!> screenchar
  1405.                 else    drop
  1406.                 then    ;
  1407.  
  1408. 0 value looked
  1409.  
  1410. : look.till     ( --- f1 )
  1411.                 off> screenchar
  1412.                 putline
  1413.                 cursor-off
  1414.                 0               \ Leave false bool in case we don't find it.
  1415.                 lastline 1+ curline 1+ over min
  1416.                 ?do     slook.buf count i #lineseg =: sseg
  1417.                         1 @> sseg 0 c@l search
  1418.                         if      =: screenchar
  1419.                                 i to.line 0=    \ change false bool to true
  1420.                                 leave           \ and leave
  1421.                         else    drop
  1422.                         then
  1423.                         i 127 and 0=
  1424.                         if      lincol statusline at
  1425.                                 I 1+ 4 >attrib1 .l >norm
  1426.                                 key? ?leave
  1427.                         then
  1428.                 loop    ?cs: =: sseg getline emptykbd ?cursor ;
  1429.  
  1430. : look.back     ( --- f1 )
  1431.                 off> screenchar putline
  1432.                 cursor-off
  1433.                 0               \ Leave false bool in case we don't find it.
  1434.                 0 curline 1- 0MAX
  1435.                 ?do     i #linelook
  1436.                         if      i backto.line 0=  \ change false bool to true
  1437.                                 leave             \ and leave
  1438.                         then
  1439.                         i 127 and 0=
  1440.                         if      lincol statusline at
  1441.                                 I 1+ 4 >attrib1 .l >norm
  1442.                                 key? ?leave
  1443.                         then
  1444.             -1 +loop    ?cs: =: sseg
  1445.                 getline emptykbd ?cursor ;
  1446.  
  1447. : <slooker>     ( --- ) ?lastline if exit then
  1448.                 off> looked slook.buf c@ 0=
  1449.                 if      rwrd    exit    \ just step to next word
  1450.                 then    putline getline
  1451.                         curline >r r@ #linelook 0=
  1452.                         ?cs: =: sseg
  1453.                 if      look.till dup =: lookflg 0=
  1454.                         if      .nofound r@ backto.line
  1455.                         else    on> looked then
  1456.                 else    on> looked
  1457.                 then    r>drop ;
  1458.  
  1459. headers
  1460.  
  1461. : slooker       ( --- )
  1462.                 ?lastline if exit then
  1463.                 ?shiftkey 0= save!> caps
  1464.                 <slooker>
  1465.                 restore> caps
  1466.                 screenline 10 <
  1467.                 if      screenline 1+ curline first.textline +
  1468.                         min =: screenline
  1469.                 then    ;
  1470.  
  1471. : slookbk       ( --- )
  1472.                 true save!> caps
  1473.                 off> looked
  1474.                 curline >r
  1475.                 look.back dup =: lookflg 0=
  1476.                 if      .nofound r@ to.line
  1477.                 else    on> looked
  1478.                 then    r>drop
  1479.                 restore> caps ;
  1480.  
  1481. : sloob         ( --- ) \ search again backwards
  1482.                 slookbk scrshow clipdown ;
  1483.  
  1484. : slooa         ( --- ) \ search again forward
  1485.                 incr> screenchar slooker scrshow sdisplay ;
  1486.  
  1487. : sloon         ( --- )
  1488.                 savescr
  1489.                 15 6 64 10 box&fill
  1490.                 ."  \r Text to look for: \0   <Enter>=accept ESC=cancel"
  1491.                 bcr
  1492.                 bcr  ."    Press Alt-A to enter a special character"
  1493.                 off> stripping_bl's     \ don't string trailing blanks
  1494.                                         \ from search string.
  1495.                 on> autoclear
  1496.                 >attrib1
  1497.                 17 8 slook.buf 29 lineeditor       ( --- f1 )
  1498.                 >norm
  1499.                 if      cursor-off
  1500.                         17 9 at ." \s13\1 Looking ...."
  1501.                         63 @> #out - spaces
  1502.                         slooa cursor-on
  1503.                 then    restscr scrshow ;
  1504.  
  1505. : sloow         ( -- )          \ search for word under cursor
  1506.                 @word@cur count slook.buf c!
  1507.                 slook.buf count cmove
  1508.                 sloon ;
  1509.  
  1510. headerless
  1511.  
  1512. create rep.buf   32 allot       rep.buf  32 erase
  1513.  
  1514. 0 value repset
  1515.  
  1516. : <srepa>       ( --- )
  1517.                 looked repset and
  1518.                 if      true save!> imode
  1519.                         slook.buf c@ 0
  1520.                         ?do     <fdel>
  1521.                                 modified putline getline
  1522.                         loop
  1523.                         rep.buf count bounds
  1524.                         ?do     i c@ schr
  1525.                         loop    off> looked
  1526.                         restore> imode
  1527.                 else    .nofound
  1528.                 then    scrshow ;
  1529.  
  1530. headers
  1531.  
  1532. : srepa         ( --- )
  1533.                 ?browse ?exit
  1534.                 <srepa> slooa   ;
  1535.  
  1536. : srepn         ( --- )
  1537.                 ?browse ?exit
  1538.                 off> repset
  1539.                 looked 0=
  1540.                 if      .nofound
  1541.                 else    savescr
  1542.                         14 6 70 10 box&fill
  1543.         ."  \r Replace found text with: \0  <Enter>=accept ESC=cancel"
  1544.                         bcr
  1545.                         bcr ." \tPress Alt-A to enter a special character"
  1546.                         off> stripping_bl's     \ don't strip trailing balnks
  1547.                                                 \ from replace string
  1548.                         on> autoclear
  1549.                         >attrib1
  1550.                         16 8 rep.buf 29 lineeditor       ( --- f1 )
  1551.                         >norm
  1552.                         if      on> repset srepa
  1553.                         then
  1554.                         restscr
  1555.                 then    scrshow ;
  1556.  
  1557. : repall        ( --- )
  1558.                 ?browse ?exit
  1559.                 first.textcol statusline at
  1560.                 ." \4 Replacing \`"
  1561.                 slook.buf count type
  1562.                 ." \` with \`"
  1563.                 rep.buf count type
  1564.                 ." \` Press ESC to cancel" >attrib4 edeeol >norm
  1565.                 looked if <srepa> then
  1566.                 begin   slooa   looked
  1567.                         key?    if key 27 <> and then
  1568.                 while   <srepa>
  1569.                 repeat  ;
  1570.  
  1571. headerless
  1572.  
  1573. : already_exists?       ( --- f1 )      \ does filename in ed2hndl exist?
  1574.                 ed2hndl hopen 0=        \ if so, then prompt for overwrite.
  1575.                 if      ed2hndl hclose drop
  1576.                         cursor-off
  1577.                         10 11 at
  1578.                         ." \r ALREADY EXISTS, overwrite it? Y/N [N] "
  1579.                         key bl or 'y' <> dup
  1580.                         if      ." \rAborting...\:05"
  1581.                                 scrshow
  1582.                         else    10 11 at 61 spaces
  1583.                         then    cursor-on
  1584.                 else    false
  1585.                 then    ;
  1586.  
  1587. headers
  1588.  
  1589. : wr->fl        ( --- )
  1590.                 savescr
  1591.                  8 6 71 12 box&fill
  1592.         ."  \r Write the file in memory to: \0    <Enter>=accept ESC=cancel"
  1593.                 ed1hndl pad over c@ 1+ cmove
  1594.                 on> autoclear
  1595.                 >attrib1
  1596.                 10 9 pad 59 lineeditor       ( --- f1 )
  1597.                 >norm
  1598.                 if      pad
  1599. \                        recover.$$$ drop
  1600.                         dup ed2hndl $>handle
  1601.                         ed2hndl pathset drop
  1602.                         already_exists?                 \ overwrite existing?
  1603.                         if      drop exit               \ if not then exit
  1604.                         then
  1605.                         ed1hndl $>handle
  1606.                         ed1hndl pathset drop
  1607.                         on> newfl on> changed
  1608.                         save> screenchar
  1609.                         save> screenline
  1610.                         curline >r
  1611.                         <shom>
  1612.                         10 11 at ." Saving As File..."
  1613.                         ?enoughdisk
  1614.                         if      put
  1615.                                 off> changed on> updated
  1616.                                 ." .DONE \:05"
  1617.                         else    showstat
  1618.                         then
  1619.                         begin   curline r@ <>
  1620.                         while   curline+
  1621.                         repeat r>drop
  1622.                         restore> screenline
  1623.                         restore> screenchar
  1624.                         getline
  1625.                 then    restscr on> ?border scrshow ;
  1626.  
  1627. headerless
  1628.  
  1629. : <joinln>      ( --- )
  1630.                 132 save!> rmargin              \ guarantee NO WRAP
  1631.                    '.' schr                     \ add an extra char
  1632.                 restore> rmargin                \ restore right margin
  1633.                 0 save!> screenchar
  1634.                    linelen dup 132 < >r >r      \ line < 132 chars long
  1635.                    sdln
  1636.                    linelen r> + 200 < r> and    \ and total chars < 200
  1637.                    if      bdel
  1638.                    else    suln
  1639.                    then
  1640.                 restore> screenchar
  1641.                 bdel ;                          \ delete extra char
  1642.  
  1643. : ?addbl        ( --- )         \ add a blank if char before cursor is NOT
  1644.                                 \ a blank, and SCREENCHAR is NOT zero.
  1645.                 screenchar ?dup 0= ?exit        \ leave if beginning of line
  1646.                 1- linebuf 1+ + c@ bl <>        \ or preceeded by a blank
  1647.                 if      bl schr
  1648.                 then    ;
  1649.  
  1650. headers
  1651.  
  1652. : joinln        ( --- )
  1653.                 ?browse ?exit
  1654.                 true save!> imode
  1655.                 0 save!> screenchar
  1656.                     sendl ?addbl <joinln> delbl's
  1657.                     modified putline getline
  1658.                 restore> screenchar
  1659.                 restore> imode
  1660.                 scrshow ;
  1661.  
  1662. : itgl          ( --- )         \ insert mode toggle
  1663.                 ?browse ?exit
  1664.                 imode 0= =: imode ?cursor ;
  1665.  
  1666. : fdel          ( --- )         \ forward delete
  1667.                 ?browse ?exit
  1668.                 screenchar linelen >=
  1669.                 if      ?addbl <joinln> delbl's
  1670.                 else    csaveon <fdel> csaveoff
  1671.                 then
  1672.                 modified putline getline
  1673.                 ?showfull drop sdisplay ;
  1674.  
  1675. : wdel          ( --- )
  1676.                 ?browse ?exit
  1677.                 screenchar linelen >=
  1678.                 if      ?addbl <joinln>         \ unwrap line
  1679.                         chrptr c@ bl =
  1680.                         if      delbl's
  1681.                         then
  1682.                 else    chrptr c@ bl <>
  1683.                         if      csaveon
  1684.                                 del<>bl's       \ delete non blank
  1685.                                 <fdel>          \ delete one blank
  1686.                                 0 csave         \ Append null delimiter
  1687.                                 csaveoff
  1688.                                 delbl's         \ and delete blanks
  1689.                         else    csaveoff
  1690.                                 delbl's
  1691.                         then                    \ for possible undelete
  1692.                 then
  1693.                 modified putline getline
  1694.                 ?showfull drop sdisplay ( scrshow ) ;
  1695.  
  1696. : mark-clear    ( -- )
  1697.                 off> marking
  1698.                 off> markstrt
  1699.                 off> markfst
  1700.                 off> markend
  1701.                 off> markdone ;
  1702.  
  1703. : mark-on/off   ( --- )
  1704.                 markdone
  1705.                 if      mark-clear
  1706.                         cursor-off
  1707.                         25 6 51 8 box&fill
  1708.                         ." \s01\r ** Mark is CLEARED ** \:07"
  1709.                         cursor-on
  1710.                 else    marking 0=
  1711.                         if      on> marking
  1712.                                 curline    =: markstrt
  1713.                                 curline    =: markend
  1714.                                 curline    =: markfst
  1715.                                 screenchar =: markchar
  1716.                         else    curline markfst >
  1717.                                 if      markfst    =: markstrt
  1718.                                         curline    =: markend
  1719.                                 else    markfst    =: markend
  1720.                                         curline    =: markstrt
  1721.                                         screenchar =: markchar
  1722.                                 then    on> markdone
  1723.                         then
  1724.                 then    scrshow ;
  1725.  
  1726. : %?mark-plus   ( -- )
  1727.                 marking markdone 0= and
  1728.                 if      curline markfst >
  1729.                         if      markfst =: markstrt
  1730.                                 curline =: markend
  1731.                         else    markfst =: markend
  1732.                                 curline =: markstrt
  1733.                         then    scrshow
  1734.                 then    ;
  1735.  
  1736. ' %?mark-plus is ?mark-plus
  1737.  
  1738. : smrk          ( --- )         \ mark line for get
  1739.                 mark-on/off ;
  1740.  
  1741. : dnln         ( --- ) sdln sdisplay emptykbd ;
  1742.  
  1743. : upln          ( --- ) suln sdisplay emptykbd ;
  1744.  
  1745. : tscrn         ( --- )
  1746.                 begin   ?firstline 0=
  1747.                         screenline first.textline <> and
  1748.                 while   upln
  1749.                 repeat  ;
  1750.  
  1751. : bscrn         ( --- )
  1752.                 begin   ?lastline 0=
  1753.                         screenline last.textline < and
  1754.                 while   dnln
  1755.                 repeat  ;
  1756.  
  1757. : scldn        ( --- )  screenline last.textline <>
  1758.                 if      decr> screenline
  1759.                         sdln scrshow
  1760.                 else    sdln
  1761.                 then    emptykbd ;
  1762.  
  1763. : sclup         ( --- ) screenline first.textline <>
  1764.                 if      incr> screenline
  1765.                         suln scrshow
  1766.                 else    suln
  1767.                 then    emptykbd ;
  1768.  
  1769. : bhyper        ( --- )
  1770.                 mxlln save!> rmargin
  1771.                 false save!> caps
  1772.                 off> looked
  1773.                 slook.buf @ >r
  1774.                 hyperchar slook.buf 1+ c! 1 slook.buf c!
  1775.                 curline >r
  1776.                 look.back dup =: lookflg 0=
  1777.                 if      .nofound r@ to.line
  1778.                 else    on> looked
  1779.                 then    curline r> - +!> screenline
  1780.                 screenline first.textline <
  1781.                 if      last.textline 6 -
  1782.                         curline first.textline + min =: screenline
  1783.                 then
  1784.                 r> slook.buf !
  1785.                 restore> caps
  1786.                 restore> rmargin scrshow sdisplay showcur ;
  1787.  
  1788. : nhyper        ( --- )         \ tab expansion word
  1789.                 slook.buf @ >r
  1790.                 hyperchar slook.buf 1+ c! 1 slook.buf c!
  1791.                 mxlln save!> rmargin
  1792.                 false save!> caps
  1793.                 incr> screenchar
  1794.                 curline >r
  1795.                 <slooker>
  1796.                 curline r> - +!> screenline     \ keep screen stable as long
  1797.                                                 \ as possible
  1798.                 screenline last.textline >=     \ then center on screen
  1799.                 if      last.textline 6 -
  1800.                         curline first.textline + min =: screenline
  1801.                 then
  1802.                 restore> caps
  1803.                 restore> rmargin
  1804.                 r> slook.buf ! scrshow ;
  1805.  
  1806. : sbtab         ( --- )         \ tab left on screen
  1807.                 ?browse
  1808.         if      bhyper
  1809.         else    lchr screenchar @> tabsize mod 0 ?do lchr loop
  1810.                 screenchar lmrgn min =: lmrgn
  1811.         then    ;
  1812.  
  1813. : stab          ( --- )         \ tab right on screen
  1814.                 ?browse
  1815.         if      nhyper
  1816.         else    @> tabsize screenchar @> tabsize mod -
  1817.                 imode
  1818.                 if      0
  1819.                        ?do      bl schr ?full
  1820.                                 screenchar lmrgn = or ?leave
  1821.                         loop
  1822.                 else    +!> screenchar
  1823.                 then    screenchar @> rmargin 1- >=
  1824.                 if      off> screenchar sdln
  1825.                 then    linebuf 1+ screenchar bl skip nip 0=
  1826.                 if      screenchar @> rmargin 6 - min =: lmrgn
  1827.                 then    scrshow
  1828.         then    ;
  1829.  
  1830. headerless
  1831.  
  1832. : <lundel>      ( --- )         \ undo line deletes
  1833.                 ldel.cnt 0= if beep exit then
  1834.                 true save!> imode
  1835.                 off> screenchar <nln> ( <suln> ) ldel>linebuf
  1836.                 modified putline getline
  1837.                 restore> imode ;
  1838.  
  1839. : .nomark       ( --- )         \ inform user no mark has been set
  1840.                 savescr cursor-off
  1841.                 ['] noop save!> dobutton
  1842.                 20 6 58 9 box&fill
  1843.                      ."  No MARK has been set, use F3 first."
  1844.                 bcr ."  Press a \r KEY \0 to continue editing."
  1845.                 beep key drop
  1846.                 restore> dobutton
  1847.                 cursor-on restscr ;
  1848.  
  1849. headers
  1850.  
  1851. : lundel        ( --- )         \ undo line deletes
  1852.                 ?browse ?exit
  1853.                 <lundel> scrshow ;
  1854.  
  1855. : sgetl         ( --- )
  1856.                 ?browse ?exit
  1857.                 markstrt lastline 2- > if exit then
  1858.                 marking 0= ?showfull or ?maxlines or if .nomark exit  then
  1859.                 true save!> imode on> changed
  1860.                 off> screenchar nln suln
  1861.                 restore> imode
  1862.                 markstrt curline >= if incr> markstrt then
  1863.                 linebuf linebuf.len blank
  1864.                 markstrt #lineseginfo 2- >r ?cs: linebuf 1+
  1865.                 r> ch/l 2+ min cmovel ch/l linebuf c!
  1866.                 modified putline getline sdln
  1867.                 incr> markstrt
  1868.                 markend markstrt max =: markend
  1869.                 scrshow ;
  1870.  
  1871. : spltln        ( --- )
  1872.                 ?browse ?exit
  1873.                 true save!> imode
  1874.                       save> screenchar
  1875.                 nln suln
  1876.                 restore> screenchar
  1877.                 restore> imode scrshow ;
  1878.  
  1879. : showscreen    ( --- )
  1880.                 showstat scrshow ?cursor ;
  1881.  
  1882.                 \ allow entry of any keyboard character
  1883. : ^cc           ( --- )
  1884.                 ?browse ?exit
  1885.                 window.left 0MAX statusline at
  1886.                 ." \2  Enter a key to insert "
  1887.                 showcur key schr ;
  1888.  
  1889. : lmset         ( --- )
  1890.                 screenchar =: lmrgn
  1891.                 savescr cursor-off
  1892.                 22 6 58 8 box&fill
  1893.                 ."  Left Margin set to column " screenchar .
  1894.                 1 seconds restscr cursor-on showcur ;
  1895.  
  1896. : tabset        ( --- )
  1897.                 screenchar 1 max dup =: tabsize =: etabsize
  1898.                 savescr cursor-off
  1899.                 22 6 58 8 box&fill
  1900.                 ."  Tabs set column increment " @> tabsize .
  1901.                 1 seconds restscr cursor-on showcur ;
  1902.  
  1903. forth definitions
  1904.  
  1905.