home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / FFA.ZIP / SEDITOR.SEQ < prev    next >
Encoding:
Text File  |  1988-01-11  |  54.1 KB  |  1,401 lines

  1. \ SEDITOR.SEQ   Sequential EDitor          Written by 1987 Tom Zimmer
  2.  
  3. ?dark
  4. .comment:
  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 imbedded
  10. portion of the FF Forth system, and may be used as needed to develop
  11. programs on that system. SED is provided in source form in the FF system
  12. to allow you the ability to change SEDs characteristics. The Forth system
  13. FF is also in the public domain, and as such you may do with FF and SED
  14. as you wish.
  15.  
  16.                                         Tom Zimmer
  17.  
  18. comment;
  19.  
  20. only forth also hidden also
  21.  
  22. editor also definitions
  23.  
  24.               1 constant real.firstline
  25.  real.firstline constant first.textline
  26.              24 constant lines/screen
  27.               0 constant statusline
  28.               1 constant helpline
  29.             250 constant ch/l
  30.             187 constant helpkey        \ default value is F1 key
  31.  
  32. lines/screen 1- constant last.textline
  33.               0 constant torig          \ origin of text in text segment
  34.            2573 constant crlfval        \ value of line terminator CRLF.
  35.            8224 constant blbl           \ value of two blanks.
  36.             255 constant linebuf.len
  37.              12 constant formfeed
  38.              55 constant prtlines       \ print lines per page
  39.  
  40. variable imode          \ insert mode flag
  41. variable lastline       \ last valid line in file.
  42. variable lmrgn
  43. variable memleft
  44. variable newfl          \ was new file created?
  45. variable changed        \ edit changed flag
  46. variable markline       \ mark/get line #
  47. variable markchar       \ mark/get character offset
  48. variable updated        \ have we updated to disk yet?
  49. variable lookflg        \ did we find anything last time?
  50. variable xrmrgn
  51. variable wrapped
  52. variable wraplen
  53. variable wraploc
  54. variable escflg         \ are we escaping during filename entry
  55. variable filtering      \ are we looking for ESC and Alt-F10?
  56. variable lchng          \ line changed flag
  57. variable ldel.cnt       \ count of line deletes
  58. variable emptyline
  59. variable lastldline     \ last line we were editing.
  60.  
  61. create nfil  13 c, 10 c, 13 c, 10 c, 13 c, 10 c, \ empty file
  62. create blnks 128 allot blnks 128 blank
  63.  
  64. 0 constant screenline           \ current screen line
  65. 0 constant curline              \ current line number
  66.  
  67. variable origcur
  68. : cursave       ( --- ) get-cursor origcur ! ;
  69. : currest       ( --- ) origcur @ set-cursor ;
  70.  
  71. defer showstat
  72. defer exit.edit         ' quit is exit.edit  \ default to just quit
  73. defer doacharx
  74. defer normkey           ' bl is normkey
  75. defer normfilter        ' noop is normfilter
  76. defer normbgstuff       ' noop is normbgstuff
  77.  
  78. variable vstaton
  79. variable statcnt
  80.  
  81. create slook.buf   36 allot     \ search buffer
  82.        slook.buf   36 blank 1 slook.buf c!
  83.  
  84. create   linebuf linebuf.len allot   linebuf linebuf.len blank
  85. create  temp.buf linebuf.len allot  temp.buf linebuf.len blank
  86. create split.buf linebuf.len allot split.buf linebuf.len blank
  87. create  wrap.buf linebuf.len allot  wrap.buf linebuf.len blank
  88. create temp2.buf linebuf.len allot temp2.buf linebuf.len blank
  89. create fdbuf     36          allot fdbuf     36          erase
  90. variable csaveflg                               \ are we saving characters
  91.  
  92. 0 constant ldel.buf
  93. 0 constant linelen
  94.  
  95. create --'s.buf 80 allot        --'s.buf 80 hex c4 decimal fill
  96.  
  97. : -s    ( n1 --- )      --'s.buf swap 0 max 80 min type ;
  98.  
  99. : gremit create c, does> c@ qemit ;
  100.  
  101. hex
  102. c0 gremit |.    c4 gremit --    b3 gremit |     d9 gremit .|
  103. bf gremit '|    da gremit |'
  104. decimal
  105.  
  106. : ss qspaces ;
  107.  
  108. : ||            ( --- ) 79 #line @ at | ;
  109.  
  110. : .l            ( n1 n2 --- )   \ Print left justified in fld
  111.                 >r (u.) dup >r type r> r> swap - 0 max
  112.                 ?dup    if  blnks swap type then ;
  113.  
  114. : emptykbd      ( --- ) \ empty any keyboard typeahead
  115.                 begin   key?
  116.                 while   key drop
  117.                 repeat  ;
  118.  
  119. hex             \ 02 = Shift key, 08 = Alt key, 40 = Caps lock.
  120.  
  121. \ : ?capslock     ( --- f1 ) 0 417 c@l 40 and 0<> ;
  122. : ?shiftkey     ( --- f1 ) 0 417 c@l 02 and 0<> ;
  123.  
  124.  
  125. decimal
  126.  
  127. : eeol          ( --- )         \ clear the screen line.
  128.                 #out @ 78 > ?exit
  129.                 blnks #out @ 79 min 79 over - swap
  130.                 #line @ vtype ;
  131.  
  132. : creeol        ( --- )         \ erase next line.
  133.                 cr eeol 0 #line @ at ;
  134.  
  135. : erase.bottom  ( --- )
  136.                 0 #line @ 24 over - 1 max 0
  137.                 do creeol loop at ;
  138.  
  139. : terminate.edit        ( --- )
  140.                 shndl+ clr-hcb
  141.                 creeol creeol ." Leaving now...." creeol
  142.                 erase.bottom exit.edit ;
  143.  
  144. : ?terror       ( f1 a1 n1 --- )        \ handle errors
  145.                 rot
  146.                 if      creeol type terminate.edit
  147.                 else    2drop then    ;
  148.  
  149. : set.newfile   ( --- )         \ setup memory for a new file
  150.                 creeol ."    New File Created "  creeol
  151.                 pad 64 blank ?cs: pad  torig tb: 64 cmovel
  152.                 4 toff ! ?cs: nfil torig tb:   4 cmovel 5 tenths ;
  153.  
  154. : ?softerror    ( bool a1 n1 --- )
  155.                 rot
  156.                 if      beep 0 statusline at >attrib4
  157.                         type eeol >norm cursor-off 2 seconds
  158.                         showstat
  159.                 else    2drop
  160.                 then    ;
  161.  
  162. : change.ext    ( a1 --- )      \ rename file in tfcb to have
  163.                 shndl @  shndl+ b/hcb cmove
  164.                 shndl+ $>ext
  165.                 shndl+ hdelete drop     \ delete old backup
  166.                 shndl @ shndl+ hrename
  167.                 dup 3 = over        5 = or swap    17 = or
  168.                 \   no path found,  access denied, no path found
  169.                 newfl @ 0= and " Rename error"  ?terror ;
  170.  
  171. : clearit       initstuff 0 dos-line c! ;
  172.  
  173. : read.openfile ( --- ) \ read a file that is already open.
  174.                 shndl @ endfile 64000. dmin drop dup toff ! >r
  175.                 creeol ." Reading... "
  176.                 shndl @ >attrib1 count type >norm creeol
  177.                 0.0 shndl @ movepointer
  178.                 torig r> shndl @ tsegb @ exhread drop ;
  179.  
  180.  
  181. : read.oldfile ( --- )         \ get existing file
  182.                 newfl off
  183.                 shndl @ endfile 64000. D>    \ > than 64k bytes?
  184.                 if      creeol
  185.                         ." WARNING ! File too BIG, reading first 64k."
  186.                         beep
  187.                         newfl on " ORG" ">$ change.ext creeol
  188.                         creeol ." Old file renamed to  --> "
  189.                         shndl+ count type creeol 2 seconds
  190.                 then    read.openfile ;
  191.  
  192. : ?diskfull     ( --- f1 )      shndl @ >nam 1+ c@ ascii : =
  193.                 if  shndl @ >nam c@ bl or 96 - else 0 then
  194.                 getdiskfree * 0 128 um/mod nip *D
  195.                 toff @  tend @ negate + 0 128 um/mod swap
  196.                 if      1+ then 0 D< dup
  197.                 if      creeol ." WARNING !!"
  198.                         creeol ." There is NO ROOM TO SAVE on disk !!"
  199.                         beep    1 seconds beep 1 seconds
  200.                 then    ;
  201.  
  202. : read.file     ( --- )         \ read file in shndl
  203.                 -1 tend ! newfl off
  204.                 shndl @ handle>ext 1+ " BAK" caps-comp 0=
  205.                 " Can't edit files with ext .BAK" ?terror
  206.                 shndl @ hopen           \ opens the file.
  207.                 if      newfl on set.newfile
  208.                 else    read.oldfile
  209.                         5 tenths
  210.                         shndl @ hclose " Close Error" ?terror
  211.                         ?diskfull drop
  212.                 then    ;
  213.  
  214. : ?change.bak   ( --- )
  215.                 newfl @ 0=
  216.                 if      " BAK" ">$ change.ext then    ;
  217.  
  218. : write.file    ( --- )         \ write file in shndl
  219.                                   \ WRITE.FILE assumes we are on FIRST line.
  220.                 shndl @ hcreate dup " Error Making File" ?softerror ?exit
  221.                 tend @ tb: torig tb: tend @ negate cmovel
  222.                 temp.buf 10 26 fill
  223.                 ?cs: temp.buf tend @ tb: negate 10 cmovel
  224.                                                 \ text to buffer beginning.
  225.                 0.0 shndl @ movepointer
  226.                 torig tend @ negate 2+ dup >r   \ +2 Control Z's
  227.                 shndl @ tsegb @ exhwrite r> <> dup
  228.                 " Error while writing, probably out of space."
  229.                 ?softerror ?exit
  230.                 shndl @ hclose " Error Closing File" ?softerror
  231.                 torig tb: tend @ tb: dup negate cmovel> ;
  232.                                                 \ text back to buffer end.
  233.  
  234. : skeyfilter    ( n1 --- n2 ) normfilter
  235.                 filtering @ 0= ?exit
  236. ( escape key )  dup  27 = if drop 13 escflg on exit then
  237. ( Alt-F10 key)  dup 241 = if drop 13 escflg on      then ;
  238.  
  239. \ ' skeyfilter is keyfilter
  240.  
  241. : getafile      ( --- f1 )
  242.                 >in @ span @ 1- >               \ entered filename?
  243.                 if      \ ['] qemit  is emit      \ change emit
  244.                         getfile                 \ no, get one from windw
  245.                         ['] (emit) is emit      \ restore emit
  246.                         if      file>tib        \ good, then to TIB
  247.                         else    span off
  248.                                 #tib off
  249.                                 >in  off
  250.                         then
  251.                 then    >in @ span @ 1- > 0=    \ if tib has name
  252.                 if      bl word
  253.                         shndl @ $>handle true   \ moveit then done
  254.                         loadline off            \ reset to first line
  255.                 else    false                   \ else no good
  256.                 then    ;
  257.  
  258. : get.filename  ( --- f1 )
  259.     begin   0 3 at escflg off filtering on
  260.         ." Press ENTER to pick an existing file, change drives, or set the path."
  261.          creeol
  262.         ." Type a NEW Filename to create and edit, or Press ESC to leave."
  263.          creeol
  264.         ." ->" query filtering off escflg @
  265.         if      creeol
  266.                 creeol ." Written by Tom Zimmer"
  267.                 creeol 11 ss     ." 292 Falcato Drive"
  268.                 creeol 11 ss     ." Milpitas, California"
  269.                 creeol 22 ss     ." Zip 95035    hm (408) 263-8859"
  270.                 creeol 35 ss                  ." wk (408) 432-4643"
  271.                 creeol
  272.                 shndl @ hopen drop      \ try to leave the file open
  273.                                           \ but don't get upset if it won't
  274.                                             \ open.
  275.                 creeol ." SED is released into the Public Domain."
  276.                 creeol false true
  277.         else    getafile ?dup
  278.         then    erase.bottom creeol
  279.     until       ;
  280.  
  281. : set.file      ( t1 --- f1 )   \ setup file name in shndl
  282.                 bl word c@
  283.                 if      here shndl @ $>handle true
  284.                 else    get.filename
  285.                 then    ;
  286.  
  287. : get           ( t1 --- f1 )      \ get a file, return true if ok
  288.                 set.file dup
  289.                 if      read.file
  290.                         shndl @ pathset " Can't read path" ?terror
  291.                 then    ;
  292.  
  293. : put           ( --- )         \ save a file
  294.                 begin   ?diskfull
  295.                 while   creeol
  296.                         ." Insert another disk, and press "
  297.                            ." 'Enter' to continue,"
  298.                         creeol ." or 'Esc' to abort"  0
  299.                         begin   drop key dup 27 = over 13 = or
  300.                         until   27 =    if      terminate.edit
  301.                                         then    dark
  302.                 repeat  write.file ;
  303.  
  304. : linebuf:      ( --- seg a1 )  \ a useful primitive
  305.                 ?cs: linebuf ;
  306.  
  307. : lineptr       ( --- a1 )      \ addr of current line
  308.                 curline >lineptr ;
  309.  
  310. : lineinfo      ( --- a1 n1 )   \ info on current line
  311.                 curline #linedata ;
  312.  
  313. : showcur       ( --- )         \ display cursor at proper loc
  314.                 screenchar 1+
  315.                 dup 78 > if 39 mod 39 + then
  316.                 screenline at ;
  317.  
  318. : #lineinfo     ( n1 --- seg a1 n2 )
  319.                 dup curline 1- =
  320.                 if      tb: >lineptr tl:@ toff @ over -
  321.                 else    tb: #linedata
  322.                 then    ;
  323.  
  324. : stripbl's     ( --- )         \ strip off trailing blanks
  325.                 0 linebuf count 0 swap 1-  0 max
  326.                ?do      i over + c@ bl <>
  327.                         if      nip i 1+ swap leave
  328.                         then
  329.             -1 +loop    drop linebuf c! ;
  330.  
  331. : restore.name  ( --- )         \ restore backup file extension
  332.                 shndl @ handle>ext 1+ temp.buf 1+ 3 cmove
  333.                 3 temp.buf c! " BAK" ">$ shndl @ $>ext
  334.                 shndl @ hopen 0=
  335.                 if      shndl @ hclose drop
  336.                         temp.buf change.ext
  337.                 then    temp.buf shndl @ $>ext ;
  338.  
  339. : getline       ( --- )         \ get current line to linebuf.
  340.                 linebuf linebuf.len blank
  341.                 lineinfo >r tb:
  342.                 linebuf: 1+ r@ ch/l 2+ min cmovel  ( --- )
  343.                 r@ 2- =: linelen
  344.                 r> linebuf + 1- dup @ crlfval =
  345.                 if      blbl swap !
  346.                 else    drop  2 +!> linelen
  347.                 then    linebuf linelen + dup c@ 9 =
  348.                 if      bl over c! decr> linelen
  349.                 then    drop ch/l linebuf c! lchng off ;
  350.  
  351. : putline       ( --- )
  352.                 lchng @ 0= ?exit        \ only save if changed
  353.                 stripbl's               \ restore linebuf to file
  354.                 linebuf count + crlfval swap !
  355.                 linebuf c@ 2+ linebuf c!
  356.                 linebuf: count >r tsegb @ lineptr dup 2+ tl:@
  357.                 linebuf c@ - dup rot tl:!
  358.                 dup tend ! r> cmovel ;
  359.  
  360. : curline+      ( --- )         \ move down one line in text
  361.                 curline lastline @ = ?exit
  362.                 lineinfo >r tb: toff @ tb: r@ cmovel
  363.                 toff @ lineptr tl:! r> toff +!
  364.                 incr> curline lineptr tl:@ tend ! ;
  365.  
  366. : curline-      ( --- )         \ move up one line in text
  367.                 curline 0= ?exit
  368.                 tsegb @ lineptr dup 2- tl:@ toff @ over - >r
  369.                 swap tl:@ r@ - tb: r@ cmovel
  370.                 r@ negate toff +!
  371.                 lineptr dup tl:@ r> - swap 2- tl:!
  372.                 decr> curline lineptr tl:@ tend ! ;
  373.  
  374. variable rsplit
  375.  
  376. : ?lf's         ( --- )         \ check for file has lf's
  377.                 0       ch/l 2+ torig   mxlln rsplit !
  378.                 do      i tb:   @l crlfval =
  379.                         if      drop -1 leave
  380.                         then
  381.                 loop    ( --- f1 )      \ true if has line feed
  382.                 0=
  383.                 if      creeol ." Splitting lines longer than "
  384.                         64 .  64 rsplit !
  385.                         creeol ." Changing EXT to .TMP" creeol
  386.                         " TMP" ">$ shndl @ $>ext newfl on  beep
  387.                         2 seconds changed on \ make it save !
  388.                 then    ;
  389.  
  390. : stripCtl-Z's  ( --- )
  391.                 toff @ dup dup 128 - swap 1-
  392.                 ?do     i tb: c@l control Z <>
  393.                         if      drop i 1+ leave
  394.                         then
  395.             -1 +loop    toff ! ;
  396.  
  397.                 \ conditional lastline and firstline tests
  398.  
  399. : ?lastline     ( --- f1 ) curline lastline @ >= ;
  400.  
  401. : ?firstline    ( --- f1 ) curline 1 < ;
  402.  
  403. : >lf           ( a1 --- a2 )   \ find the next linefeed in file
  404.                 tsegb @ sseg !          \ seg search segment
  405.                 dup ch/l 10 scan 0=
  406.                 if      drop rsplit @ 1-
  407.                 else    over -
  408.                 then    xrmrgn @ over max xrmrgn ! +
  409.                 ?cs: sseg ! ;
  410.  
  411. : build.linelist ( --- )
  412.                 tend @  maxlines 1- 0
  413.                 do      incr> curline
  414.                         >lf 1+ dup lineptr tl:! dup 0= ?leave
  415.                 loop    drop ;
  416.  
  417. : sinit         ( --- ) \ initialize file, and linelist table
  418.                 changed off
  419.                 ?lf's stripCtl-Z's imode on -1 markline !
  420.                 torig tb: toff @ tb: dup negate swap cmovel>
  421.                 toff @ negate tend ! toff off
  422.                 updated off lookflg off
  423.                 0 =: curline lmrgn off first.textline
  424.                 =: screenline 0 =: screenchar   xrmrgn off
  425.                 tend @ lineptr tl:!
  426.                 build.linelist
  427.                 curline 1- lastline ! 0 =: curline getline ;
  428.  
  429. : sltype        ( n1 --- ) \ n1 is data line
  430.                 dup lastline @ =                \ If last file line
  431.                 over prtlines qmod 0= over or   \ or first page line
  432.                 ( --- n1 f1 f2 )        \ f1 is lastline,
  433.                                         \ f2 is firstpage, or lastline
  434.                 if      if      30
  435.                         else    31
  436.                         then    qemit
  437.                 else    drop    \ throw away f1, it wasn't needed
  438.                         |
  439.                 then    >norm
  440.                 tsegb @ vtseg !              \ set VTYPE source segment
  441.                 dup curline 1- =
  442.                 if      >lineptr tl:@ toff @ over -
  443.                 else    #linedata
  444.                 then    2- clipline 0 max type
  445.                 ?cs: vtseg !                 \ restore VTYPE source segment
  446.                 eeol >norm || ;
  447.  
  448. : <statfunc>    ( --- ) \ show file status to user
  449.                 >attrib1
  450.                 ."   Row="       curline              1+ 5 .l
  451.                 ." Column="      screenchar              4 .l
  452.                 ."  Page#="      curline prtlines /   1+ 4 .l
  453.                 ."  Lines="      lastline           @ 1+ 5 .l
  454.                 ."  Characters=" tend @ negate toff @  + 5 .l
  455.                 ( eeol ) >norm 79 #out @ 79 min - 0 max -s '|
  456.                 0 last.textline 1+ at |.
  457.                 shndl @ count dup 16 + 79 swap - 2 /mod swap >r >r
  458.                 r@ 1- >norm -s >attrib1
  459.                 ."  Current file = " over + swap
  460.                 ?do i c@ qemit loop
  461.                 ."  " >norm r> r> + ( 1+ ) 1- 0 max -s .|
  462.                 2 last.textline 1+ at >attrib4 ."  HELP=F1 " >norm ;
  463.  
  464. : fullfunc      ( --- ) \ status for when file is full > 64k
  465.                 0 statusline at |' 4 -s >attrib1
  466.                 >boldblnk ." MEM FULL" >norm <statfunc> ;
  467.  
  468. : statfunc      ( --- )
  469.                 0 statusline at |' 4 -s >attrib1
  470.                 imode @
  471.                 if      >attrib4     ."  INSERT "
  472.                 else    >attrib1     ." OVERTYPE"
  473.                 then    >norm <statfunc> ;
  474.  
  475. ' statfunc is showstat
  476.  
  477. lines/screen 1- constant lsl    \ last screen line
  478.  
  479. : ?full         ( --- f1 )      \ is memory full?
  480.                 tend @ negate toff @ + 0 64000. d> ;
  481.  
  482. : ?showfull     ( --- )         \ set status func for memory
  483.                 ?full dup       \ condition
  484.                 if      ['] fullfunc is showstat
  485.                 else    ['] statfunc is showstat
  486.                 then    ;
  487.  
  488. : ?maxlines     ( --- f1 )
  489.                 lastline @ 4 + maxlines > ;
  490.  
  491. : sdisp         ( --- )
  492.                 0 screenline at
  493.                 curline prtlines qmod 0= ?lastline or
  494.                 if      ?lastline
  495.                         if 30 else 31 then qemit
  496.                 else    |
  497.                 then    linebuf 1+ linelen clipline
  498.                         0 max 78 min type eeol >norm || ;
  499.  
  500.  
  501. : scrshow       ( --- )         \ display screen full of file.
  502.                 cursor-off
  503.                 first.textline curline screenline
  504.                 first.textline - -
  505.                 0 max dup last.textline 1+ first.textline -
  506.                 + swap
  507.                 do      i curline =     >norm
  508.                         if      sdisp
  509.                         else    0 over at i lastline @ <=
  510.                                 if      i sltype
  511.                                 else    | eeol ||
  512.                                 then    >norm
  513.                         then    1+
  514.                 loop    drop >norm cursor-on ;
  515.  
  516. : <sdln>        ( --- )
  517.                 putline curline+ getline ;
  518.  
  519. : <suln>        ( --- )         \ sequential line down
  520.                 putline curline- getline ;
  521.  
  522. : sdisplay      ( --- )         \ display current screen line.
  523.                 cursor-off sdisp cursor-on ;
  524.  
  525. : ins.linelist  ( --- )         \ add new entry to line pointer
  526.                 lineptr tl: dup 2+ tl:   \ list.
  527.                 maxlines curline - 1- 2* cmovel>
  528.                 lastline incr ;
  529.  
  530. : ?appendline   ( --- )
  531.                 ?lastline
  532.                 if      lineptr 2+ dup tl:@ swap 2+ tl:!
  533.                         lastline incr
  534.                 then    ;
  535.  
  536. : clipdown      ( --- )
  537.                 screenline >r
  538.                 last.textline lastline @ curline - 0 max -
  539.                 screenline max last.textline min
  540.                 curline first.textline + min
  541.                 dup =: screenline r> <>
  542.                 if      scrshow then    ;
  543.  
  544. : sdln          ( --- )         \ sequential line down
  545.                 ?lastline ?exit
  546.                 <sdln> incr> screenline clipdown ;
  547.  
  548. : <shom>        ( --- )         \ home to beginning of file
  549.                 putline
  550.                 begin   ?firstline 0=
  551.                 while   curline-
  552.                 repeat  first.textline =: screenline
  553.                 0 =: screenchar lmrgn off
  554.                 getline ;
  555.  
  556. : shom          ( --- )
  557.                 <shom> scrshow ;
  558.  
  559. : suln         ( --- )         \ sequential line down
  560.                 ?firstline if exit then
  561.                 <suln> decr> screenline screenline >r
  562.                 screenline first.textline - curline min
  563.                 0 max first.textline + dup =: screenline r> <>
  564.                 if      scrshow
  565.                 then    ;
  566.  
  567. : ?cursor       ( --- )
  568.                 imode @
  569.                 if      med-cursor else norm-cursor then ;
  570.  
  571. : line>ldel.buf ( --- )
  572.                 dseg @
  573.                 if      dseg @ ldel.buf 2dup mxlln +
  574.                         ldel.cnt @ maxdline 1- min mxlln * cmovel>
  575.                         ldel.cnt dup @ 1+ maxdline 1- min swap !
  576.                         linelen linebuf c! ?cs: linebuf dseg @ ldel.buf
  577.                         linelen 1+ mxlln min cmovel
  578.                 then    ;
  579.  
  580. : ldel>linebuf  ( --- )
  581.                 dseg @
  582.                 if      dseg @ ldel.buf 2dup c@l
  583.                         ?cs: linebuf rot 1+ cmovel
  584.                         linebuf c@ =: linelen
  585.                         dseg @ ldel.buf 2dup mxlln + 2swap
  586.                         ldel.cnt @ maxdline min dup 1- ldel.cnt !
  587.                         mxlln * cmovel
  588.                 then    ;
  589.  
  590. : <ldel>        ( --- )         \ delete the current line.
  591.                 ?appendline
  592.                 line>ldel.buf
  593.                 lineptr dup 2+ tl:@ tend !
  594.                 maxlines >lineptr over - >r
  595.                 tl: dup 2+ tl: 2swap r> cmovel
  596.                 lastline decr getline changed on
  597.                 lchng on ?showfull drop ;
  598.  
  599. : ldel          ( --- ) <ldel> scrshow ;
  600.  
  601. : to.line       ( n1 --- )
  602.                 begin   curline over <
  603.                         ?lastline 0= and
  604.                 while   curline+ repeat  drop getline ;
  605.  
  606. : backto.line   ( n1 --- )
  607.                 begin   curline over >
  608.                 while   curline- repeat  drop getline ;
  609.  
  610. : .elapse       ( --- )
  611.                 ." Edit time " time-elapsed b>t
  612.                 ttime 2@ <.time> ;
  613.  
  614. : updt          ( --- )         \ save changes if any to disk.
  615.                 changed @ 0=
  616.                 if      0 statusline at >attrib2 "     No Changes to save"
  617.                         type eeol >norm showcur 5 tenths
  618.                 else    screenchar >r
  619.                         screenline >r curline >r 0 statusline at
  620.                         >attrib2 ."     Saving Changes to " .file eeol >norm
  621.                         shom put r> to.line
  622.                         r> =: screenline r> =: screenchar
  623.                         scrshow changed off updated on
  624.                 then    ?cursor emptykbd fdbuf off ;
  625.  
  626. : squt          ( f1 --- f2 )   \ discard changes and exit
  627.                 dark 0 2 at .elapse
  628.                 loadline off
  629.                 lastldline off
  630.                 updated @ 0=
  631.                 if     restore.name     then
  632.                 ." Edit Aborted on " .file eeol drop -1
  633.                 edready off ;
  634.  
  635. : <sesc>        ( f1 --- f2 )   \ save changes and exit
  636.                 curline 0=
  637.                 if      loadline off
  638.                 else    curline 1- #lineinfo + nip loadline !
  639.                         curline lastldline !
  640.                 then
  641.                 shom dark 0 2 at .elapse
  642.                 changed @
  643.                 if      ."  Saving Changes to " .file put
  644.                 else    updated @ 0= if restore.name then
  645.                         ."  No changes to save in " .file
  646.                 then    eeol
  647.                 drop -1 changed off ;
  648.  
  649. : sesc          ( f1 --- f2 )   \ save changes and exit
  650.                 ?shiftkey
  651.                 if   squt else <sesc> then ;
  652.  
  653. defer <nlnx>      ' noop is <nlnx>
  654.  
  655.                 \ conditionally add a line
  656. : ?addline      ( -- )
  657.                 ?lastline
  658.                 if      screenchar
  659.                         ch/l =: screenchar
  660.                         <nlnx>
  661.                         =: screenchar
  662.                 then    ;
  663.  
  664. : rchr          ( --- )         \ right a character
  665.                 screenchar 1+ ch/l 1- min dup =: screenchar
  666.                 rmargin @ >=
  667.                 if      0 =: screenchar ?addline
  668.                         sdln scrshow
  669.                 then    screenchar 39 - 39 /mod 0<> swap 0= and
  670.                 if      scrshow then    ;
  671.  
  672. : chrptr        ( --- a1 )      \ cur character line pointer
  673.                 screenchar linebuf 1+ + ;
  674.  
  675.                                 \ goto beginning of curent line
  676. : shoml         ( --- ) 0 =: screenchar lmrgn off scrshow ;
  677.  
  678. : sendl         ( --- )         \ goto end of current line
  679.                 linelen =: screenchar scrshow ;
  680.  
  681. : send          ( --- )         \ goto end of file
  682.                 putline
  683.                 begin   ?lastline 0=
  684.                 while   curline+
  685.                 repeat  last.textline =: screenline
  686.                 getline sendl ;
  687.  
  688. : ?leftshow     ( --- )         \ reshow screen of screen scrolled
  689.                 screenchar 39 /mod 0<> swap 38 = and
  690.                 if      scrshow
  691.                 then    ;
  692.  
  693. : lchr          ( --- )         \ left a character
  694.                 -1 +!> screenchar screenchar 0<
  695.                 if      0 =: screenchar suln
  696.                         sendl scrshow
  697.                 then    ?leftshow ;
  698.  
  699. : ?showstatus   ( --- ) normbgstuff
  700.                 vstaton @ 0= if exit then
  701.                 statcnt @ 200 >
  702.                 if      statcnt off  vstaton off
  703.                         #out @ #line @ showstat at ?cursor
  704.                 then    statcnt incr ;
  705.  
  706. \ ' ?showstatus is bgstuff
  707.  
  708. : statkey       ( --- c1 )
  709.                 normkey statcnt off ;
  710.  
  711. \ ' statkey is key
  712.  
  713. : pdn           ( --- )         \ go down a page in file
  714.                 ?lastline if exit then
  715.                 putline getline
  716.                 last.textline 1+ first.textline - 2- 0 max 0
  717.                ?do      putline curline+ getline
  718.                         ?lastline
  719.                         if      last.textline =: screenline
  720.                                 leave
  721.                         then
  722.                 loop    clipdown scrshow emptykbd ;
  723.  
  724. : pup           ( --- )         \ go up a page in file
  725.                 ?firstline if exit then
  726.                 putline getline
  727.                 last.textline 1+ first.textline - 2- 0 max 0
  728.                ?do      putline curline- getline
  729.                         ?firstline
  730.                         if      first.textline =: screenline
  731.                                 leave
  732.                         then
  733.                 loop    screenline first.textline curline +
  734.                 min     =: screenline scrshow emptykbd ;
  735.  
  736. : >space        ( --- )         \ move to next space in line
  737.                 linelen dup screenchar over min
  738.                 ?do     linebuf 1+ i + c@ dup bl =
  739.                         swap 127 > or
  740.                         if      drop i leave
  741.                         then
  742.                 loop    =: screenchar   ;
  743.  
  744. : space>        ( --- )         \ move to non blank in line
  745.                 linelen dup screenchar over min
  746.                 ?do     linebuf 1+ i + c@ dup bl <>
  747.                         swap 127 > 0= and
  748.                         if      drop i leave
  749.                         then
  750.                 loop    linelen min =: screenchar ;
  751.  
  752. : <<space>      ( ---  f1 )     \ t1 = true if found space
  753.                 0 dup screenchar
  754.                 ?do     linebuf 1+ i + c@ dup bl =
  755.                         swap 127 > or
  756.                         if      drop i leave
  757.                         then
  758.             -1 +loop    dup =: screenchar ;
  759.  
  760. : <text         ( --- )      \ move to previous text in line.
  761.                 0 dup screenchar
  762.                 ?do     linebuf 1+ i + c@ dup bl <>
  763.                         swap 127 > 0= and
  764.                         if      drop i leave
  765.                         then
  766.             -1 +loop    =: screenchar ;
  767.  
  768. : rwrd          ( --- )
  769.                 screenchar linelen rmargin @ min =
  770.                 ?lastline 0= and
  771.                 if      0 =: screenchar sdln
  772.                         scrshow exit
  773.                 then    >space
  774.                 screenchar linelen >=
  775.                 if      scrshow exit
  776.                 then    space>
  777.                 scrshow ;
  778.  
  779. : lwrd          ( --- )         \ go back to previous word.
  780.                 screenchar 0= ?firstline   0= and
  781.                 if      suln linelen =: screenchar
  782.                         scrshow exit
  783.                 then    screenchar 1- 0 max =: screenchar
  784.                 <text   screenchar 0=
  785.                 if      scrshow exit
  786.                 then    <<space>
  787.                 if      incr> screenchar
  788.                 then    rmargin @ screenchar min =: screenchar
  789.                 scrshow ;
  790.  
  791. : splitline     ( --- )
  792.                 linebuf screenchar + 1+ dup split.buf 1+
  793.                 linelen screenchar - 1+ 0 max dup >r cmove
  794.                 r> split.buf c! ch/l screenchar - blank
  795.                 screenchar =: linelen
  796.                 ?appendline
  797.                 lchng on <sdln>
  798.                 linebuf linebuf.len blank
  799.                 split.buf count linebuf 1+ lmrgn @ + swap cmove
  800.                 split.buf c@ lmrgn @ + dup linebuf c! =: linelen
  801.                 ins.linelist
  802.                 lchng on <suln> ;
  803.  
  804. : <nln>         ( --- ) \ inserts line if in insert mode.
  805.                 ?showfull ?maxlines or
  806.                 if beep exit then
  807.                 imode @
  808.                 if      SplitLine
  809.                 else    ?lastline
  810.                         if      stripbl's
  811.                                 linebuf c@ =: screenchar
  812.                                 SplitLine
  813.                         then
  814.                 then    changed on ;
  815.  
  816. ' <nln> is <nlnx>
  817.  
  818. : nln           ( --- ) \ next line function
  819.                         \ inserts line if in insert mode.
  820.                 <nln>   sdln
  821.                 lmrgn @ dup =: screenchar
  822.                 linelen max =: linelen
  823.                 ch/l linebuf c!
  824.                 scrshow ;
  825.  
  826. : csaveon       csaveflg on ;
  827.  
  828. : csaveoff      csaveflg off ;
  829.  
  830. : csave         ( c1 --- )
  831.                 csaveflg @ 0= if drop exit then \ leave if not saving chars.
  832.                 fdbuf c@ 32 >
  833.                 if      fdbuf count >r dup 1+ swap r> cmove
  834.                         fdbuf c@ 1- 0 max fdbuf c!
  835.                 then    fdbuf count + c!
  836.                         fdbuf c@ 1+ fdbuf c! ;
  837.  
  838. : <fdel>        ( --- )
  839.                 screenchar dup linebuf + 1+ dup c@ csave
  840.                 dup 1+ swap
  841.                 rot ch/l 1+ swap - cmove changed on
  842.                 lchng on ?showfull drop
  843.                 decr> linelen ;
  844.  
  845. : split.lineend ( --- )
  846.                 wrap.buf linebuf.len blank
  847.                 rmargin @ 1- =: screenchar <<space> drop
  848.                 screenchar 1+ lmrgn @ 1+ max  ( was 2+ *** )
  849.                 dup >r =: screenchar
  850.                 linebuf screenchar linelen over - 0 max >r +
  851.                 1+ dup wrap.buf 1+ r@ cmove
  852.                 r@ wrap.buf c!
  853.                 r> blank lchng on
  854.                 putline getline wrapped @ 0=
  855.                 if      wrap.buf c@ wraplen !
  856.                         wrapped on r@ wraploc !
  857.                 then    r> drop ;
  858.  
  859. : prepend.split ( --- )
  860.                 linebuf 1+ rmargin @ bl skip 0=
  861.                 wrap.buf c@ rmargin @ > or
  862.         if      drop linebuf 1+ lmrgn @ +
  863.                 0 =: screenchar <nln> 0 =: screenchar
  864.         else    wrap.buf c@ 1+ >r linebuf 1+ dup r@ +
  865.                 linelen 1+ r@ + ch/l min r@ - cmove>
  866.                 linebuf 1+ r> blank
  867.         then    ch/l linebuf c! dup linebuf 1+ -
  868.                 rmargin @ 2 - min lmrgn ! ( was 6 - *** )
  869.                 >r wrap.buf count r@ swap cmove
  870.                 wrap.buf c@ 1+ +!> linelen
  871.                 wrap.buf c@ r> linebuf 1+ - + =: screenchar
  872.                 lchng on putline getline ;
  873.  
  874. defer showst    ' showstat is showst
  875.  
  876. : ?lmargin      ( --- )
  877.                 screenchar 0=
  878.                 if      lmrgn @ =: screenchar then ;
  879.  
  880. : ?right        ( --- )
  881.                 wrapped @
  882.                 if      screenchar wraploc @ <
  883.                         if      rchr ?lmargin
  884.                         else    screenchar wraploc @ -
  885.                                 lmrgn @ + 1+ =: screenchar
  886.                                 sdln
  887.                         then    scrshow
  888.                 else    rchr    ?lmargin
  889.                 then    ;
  890.  
  891. : del<>bl's     ( --- )         \ delete non blanks
  892.                 begin   chrptr c@ bl <>
  893.                 while   <fdel>
  894.                 repeat  ;
  895.  
  896. : delbl's       ( --- )         \ delete blanks
  897.                 rmargin @ screenchar
  898.                 ?do      chrptr c@ bl <> ?leave <fdel>
  899.                 loop    ;
  900.  
  901. : AppendLine    ( --- )         \ append this line to previous.
  902.                 ?firstline if beep exit then imode @
  903.         if      stripbl's split.buf linebuf.len blank
  904.                 linebuf split.buf over c@ dup >r 1+ cmove
  905.                 curline 1- #lineinfo nip nip r> + ch/l 1- >
  906.                 if      beep getline 0 =: screenchar
  907.                 else    ?lastline 0= if ldel then suln stripbl's
  908.                         split.buf count linebuf count 1+
  909.                         dup >r + swap cmove  lchng on split.buf c@ r@ +
  910.                         ch/l 10 - min dup 10 + linebuf c! =: linelen
  911.                         r> rmargin @ 1- min =: screenchar putline
  912.                         screenchar linelen 1- min =: screenchar
  913.                 then
  914.         else    suln stripbl's linebuf c@ =: screenchar
  915.         then    getline sdisplay ;
  916.  
  917. : bdel          ( --- )         \ back delete
  918.                 screenchar 0=
  919.                 if      AppendLine scrshow
  920.                 else    imode @
  921.                         if      screenchar dup linebuf + 1+ dup 1-
  922.                                 rot ch/l 1+ swap - cmove
  923.                                 decr> screenchar
  924.                                 linelen 1- screenchar max linelen min
  925.                                 =: linelen
  926.                         else    decr> screenchar
  927.                                 bl chrptr c! lchng on putline getline
  928.                         then    sdisplay screenchar lmrgn @ min lmrgn !
  929.                 then    lchng on changed on
  930.                 ?showfull drop ?leftshow ;
  931.  
  932. : schr          ( c1 --- )    \ insert sequential char in line.
  933.                 ?showfull ?exit
  934.                 screenchar linelen max =: linelen
  935.                 imode @
  936.         if      screenchar linebuf 1+ + dup 1+
  937.                 linelen screenchar - 0 max cmove> incr> linelen
  938.         then    dup screenchar linebuf 1+ + c!  bl <>
  939.                 if      linelen screenchar 1+ max =: linelen
  940.                 then    sdisplay changed on lchng on
  941.                 ( ?wrap  ) ?right  ;
  942.  
  943. : wudel         ( --- )
  944.                 imode dup @ >r on
  945.                 fdbuf count bounds
  946.                 ?do     fdbuf 1+ c@ >r                  \ get char
  947.                         fdbuf 2+ fdbuf 1+               \ source destination
  948.                         fdbuf c@ 1- 0 max cmove         \ clip char out
  949.                         fdbuf c@ 1- 0 max fdbuf c!      \ reduce count
  950.                         r> ?dup 0= ?leave               \ leave if null
  951.                         schr                            \ insert it
  952.                 loop    r> imode ! ;
  953.  
  954. : #linelook     ( n1 --- f1 )   \ look through line n1
  955.                 >r slook.buf count r> #lineinfo rot drop
  956.                 screenchar - 0 max swap screenchar + swap
  957.                 search swap over
  958.                 if      +!> screenchar
  959.                 else    drop
  960.                 then    ;
  961.  
  962. variable inputline
  963. variable looked
  964.  
  965. : input$        ( a1 n1 -- a2 ) escflg off filtering on
  966.                 1 inputline @ at >attrib1 type
  967.                 #out @ eeol      >norm
  968.                 inputline @ at
  969.                 pad 1+ dup 66 blank 64 expect
  970.                 pad span @ over c! filtering off ;
  971.  
  972. : look.till     ( --- f1 )
  973.                 0 =: screenchar
  974.                 putline
  975.                 tsegb @ sseg !
  976.                 0               \ Leave false bool in case we don't find it.
  977.                 lastline @ 1+ curline 1+ over min
  978.                 ?do     slook.buf count i #linedata search
  979.                         if      =: screenchar
  980.                                 i to.line 0=    \ change false bool to true
  981.                                 leave           \ and leave
  982.                         else    drop
  983.                         then    key? ?leave
  984.                         i 31 and 0=
  985.                         if      cursor-off 19 statusline at
  986.                                 I 1+ 4 >attrib1 .l >norm
  987.                         then
  988.                 loop    ?cs: sseg !
  989.                 getline emptykbd ?cursor ;
  990.  
  991. : look.back     ( --- f1 )
  992.                 0 =: screenchar
  993.                 putline 0
  994.                 tsegb @ sseg !
  995.                 0               \ Leave false bool in case we don't find it.
  996.                 0 curline 1- 0 max
  997.                 ?do     i #linelook
  998.                         if      i backto.line 0=  \ change false bool to true
  999.                                 leave             \ and leave
  1000.                         then    key? ?leave
  1001.                         i 31 and 0=
  1002.                         if      cursor-off 19 statusline at
  1003.                                 I 1+ 4 >attrib1 .l >norm
  1004.                         then
  1005.             -1 +loop    ?cs: sseg !
  1006.                 getline emptykbd ?cursor ;
  1007.  
  1008. : <slooker>     ( --- ) ?lastline if exit then
  1009.                 looked off slook.buf c@ 0=
  1010.                 if      rwrd    exit    \ just step to next word
  1011.                 then    putline getline
  1012.                         tsegb @ sseg !
  1013.                         curline >r r@ #linelook 0=
  1014.                         ?cs: sseg !
  1015.                 if      look.till dup lookflg ! 0=
  1016.                         if      beep  r@ backto.line
  1017.                         else    looked on then
  1018.                 else    looked on
  1019.                 then    r> drop
  1020.                 screenline 10 <
  1021.                 if      screenline 1+ curline first.textline +
  1022.                         min =: screenline
  1023.                 then    ;
  1024.  
  1025. : slooker       ( --- ) ?lastline if exit then
  1026.                 caps @ >r ?shiftkey
  1027.                 if      caps off else caps on then
  1028.                 <slooker> r> caps ! ;
  1029.  
  1030. : slookbk       ( --- )
  1031.                 caps @ >r looked off caps on
  1032.                 curline >r look.back dup lookflg ! 0=
  1033.                 if      beep  r@ to.line
  1034.                 else    looked on
  1035.                 then
  1036.                 r> drop r> caps ! ;
  1037.  
  1038. : sloob         ( --- ) \ search again backwards
  1039.                 slookbk scrshow ;
  1040.  
  1041. : slooa         ( --- ) \ search again forward
  1042.                 incr> screenchar slooker scrshow sdisplay ;
  1043.  
  1044. : sloon         ( --- )
  1045.                 first.textline inputline !
  1046.                 " Text to look for ->"  input$  escflg @
  1047.                 if      drop scrshow exit then dup c@
  1048.                 if      slook.buf over c@ 1+ 30 min cmove
  1049.                         slook.buf dup c@ 30 min swap c!
  1050.                 else    drop then
  1051.                 1 first.textline at >attrib1 ." Looking for .... ->"
  1052.                 #out @ eeol first.textline at
  1053.                 slook.buf count type >norm slooa ;
  1054.  
  1055. create rep.buf  128 allot       rep.buf 128 erase
  1056.  
  1057. variable repset
  1058.  
  1059. : <srepa>       ( --- )
  1060.                 looked @ 0= repset @ 0= or if beep exit then
  1061.                 imode dup @ >r on
  1062.                 slook.buf c@ 0
  1063.                 ?do     <fdel>
  1064.                         lchng on changed on putline getline
  1065.                 loop
  1066.                 rep.buf count bounds
  1067.                 ?do     i c@ schr
  1068.                 loop    looked off
  1069.                 r> imode ! scrshow ;
  1070.  
  1071. : srepa         ( --- ) <srepa> slooa   ;
  1072.  
  1073. : srepn         ( --- )
  1074.                 repset off
  1075.                 looked @ 0= if beep exit then
  1076.                 first.textline inputline !
  1077.                 " Replace with ->"  input$  escflg @
  1078.                 if      drop scrshow exit then dup c@
  1079.                 if      rep.buf over c@ 1+ 30 min cmove
  1080.                         rep.buf dup c@ 30 min swap c!
  1081.                 else    drop
  1082.                 then    repset on srepa ;
  1083.  
  1084. : repall        ( --- )
  1085.                 looked @ if <srepa> then
  1086.                 begin   slooa  looked @
  1087.                 while   <srepa>  repeat ;
  1088.  
  1089. : wr->fl        ( --- )
  1090.                 first.textline inputline !
  1091.                 " Write to Filename->"  input$
  1092.                 dup c@ escflg @ 0= and
  1093.                 if
  1094.                         restore.name shndl @ $>handle
  1095.                         shndl @ pathset " Can't read path" ?terror
  1096.                         screenchar >r   newfl on  changed on
  1097.                         screenline >r curline >r 0 statusline at
  1098.                         ." *** Saving to File *** " eeol shom put
  1099.                         begin   curline r@ <>
  1100.                         while   curline+
  1101.                         repeat r> drop r> =: screenline
  1102.                         r> =: screenchar
  1103.                         getline changed off updated on
  1104.                 else    drop
  1105.                 then    scrshow ;
  1106.  
  1107. : <joinln>      ( --- )
  1108.                 screenchar >r
  1109.                 sdln 0 =: screenchar bdel
  1110.                 r> =: screenchar ;
  1111.  
  1112. : joinln        ( --- )
  1113.                 imode dup @ >r on
  1114.                 <joinln> r> imode ! ;
  1115.  
  1116. : itgl          ( --- )         \ insert mode toggle
  1117.                 imode @ 0= imode ! ?cursor ;
  1118.  
  1119. : fdel          ( --- )         \ forward delete
  1120.                 screenchar linelen >=
  1121.                 if      bl schr
  1122.                         <joinln> delbl's
  1123.                 else    csaveon <fdel> csaveoff
  1124.                 then
  1125.                 lchng on changed on putline getline
  1126.                 ?showfull drop sdisplay ;
  1127.  
  1128. : wdel          ( --- )
  1129.                 screenchar linelen >=
  1130.                 if      bl schr
  1131.                         <joinln>                \ unwrap line
  1132.                         chrptr c@ bl =
  1133.                         if      delbl's
  1134.                         then
  1135.                 else    chrptr c@ bl <>
  1136.                         if      csaveon
  1137.                                 del<>bl's       \ delete non blank
  1138.                                 <fdel>          \ delete one blank
  1139.                                 0 csave         \ Append null delimiter
  1140.                                 csaveoff
  1141.                                 delbl's         \ and delete blanks
  1142.                         else    csaveoff
  1143.                                 delbl's
  1144.                         then                    \ for possible undelete
  1145.                 then
  1146.                 lchng on changed on putline getline
  1147.                 ?showfull drop sdisplay ( scrshow ) ;
  1148.  
  1149. : smrk          ( --- )         \ mark line for get
  1150.                 curline markline ! screenchar markchar !
  1151.                 0 statusline at ." --- Mark is Set ---" eeol
  1152.                 5 tenths ;
  1153.  
  1154. : sbtab         ( --- )         \ tab left on screen
  1155.                 lchr screenchar tabsize @ mod 0 ?do lchr loop ;
  1156.  
  1157. : dnln         ( --- ) sdln sdisplay emptykbd ;
  1158.  
  1159. : upln          ( --- ) suln sdisplay emptykbd ;
  1160.  
  1161. : tscrn         ( --- )
  1162.                 begin   ?firstline 0=
  1163.                         screenline first.textline <> and
  1164.                 while   upln
  1165.                 repeat  ;
  1166.  
  1167. : bscrn         ( --- )
  1168.                 begin   ?lastline 0=
  1169.                         screenline last.textline < and
  1170.                 while   dnln
  1171.                 repeat  ;
  1172.  
  1173. : scldn        ( --- )  screenline last.textline <>
  1174.                 if      decr> screenline
  1175.                         sdln scrshow
  1176.                 else    sdln
  1177.                 then    emptykbd ;
  1178.  
  1179. : sclup         ( --- ) screenline first.textline <>
  1180.                 if      incr> screenline
  1181.                         suln scrshow
  1182.                 else    suln
  1183.                 then    emptykbd ;
  1184.  
  1185. : stab          ( --- )         \ tab right on screen
  1186.                 tabsize @ screenchar tabsize @ mod - imode   @
  1187.                 if      0
  1188.                        ?do      bl schr ?full
  1189.                                 screenchar lmrgn @ = or ?leave
  1190.                         loop    changed on
  1191.                 else    +!> screenchar
  1192.                 then    screenchar rmargin @ 1- >=
  1193.                 if      0 =: screenchar sdln
  1194.                 then    linebuf 1+ screenchar bl skip nip 0=
  1195.                 if      screenchar rmargin @ 6 - min lmrgn !
  1196.                 then    scrshow ;
  1197.  
  1198. : tabxp         ( --- )         \ tab expansion word
  1199.                 9 slook.buf 1+ c! 1 slook.buf c!
  1200.                 xrmrgn off
  1201.                 mxlln rmargin !   caps @ >r caps off
  1202.                 shom
  1203.                 begin   incr> screenchar <slooker>
  1204.                         looked @
  1205.                 while   fdel   stab lchr
  1206.                         xrmrgn  @ linelen max xrmrgn !
  1207.                 repeat  shom
  1208.                 r> caps !
  1209.                 xrmrgn @ 2+ mxlln min 80 max rmargin ! ;
  1210.  
  1211. : lundel        ( --- )         \ undo line deletes
  1212.                 ldel.cnt @ 0= if beep exit then
  1213.                 imode dup @ >r on
  1214.                 0 =: screenchar nln suln ldel>linebuf
  1215.                 changed on lchng on putline getline
  1216.                 r> imode ! scrshow ;
  1217.  
  1218. : sgetl         ( --- )
  1219.                 markline @ lastline @ 2- > if beep exit then
  1220.                 markline @ -1 =
  1221.                 ?showfull or ?maxlines or if beep exit  then
  1222.                 imode @ >r imode on     changed on
  1223.                 0 =: screenchar nln suln r> imode !
  1224.                 markline @ curline >= if markline incr then
  1225.                 linebuf linebuf.len blank
  1226.                 markline @ #lineinfo 2- >r ?cs: linebuf 1+
  1227.                 r> ch/l 2+ min cmovel ch/l linebuf c!
  1228.                 lchng on putline getline sdln
  1229.                 markline incr scrshow ;
  1230.  
  1231. : spltln        ( --- )
  1232.                 imode dup @ >r on
  1233.                 screenchar >r
  1234.                 nln suln r> =: screenchar
  1235.                 r> imode ! scrshow ;
  1236.  
  1237. : showscreen    ( --- )
  1238.                 showstat scrshow ?cursor ;
  1239.  
  1240.                 \ allow entry of any keyboard character
  1241. : ^cc           ( --- )
  1242.                 0 0 at >attrib2
  1243.                 ."  Enter a key to insert" eeol >norm
  1244.                 showcur key schr ;
  1245.  
  1246. : lmset         ( --- ) screenchar lmrgn ! ;
  1247.  
  1248. : tabset        ( --- ) screenchar tabsize ! ;
  1249.  
  1250. : notavail      ( --- )
  1251.              0 statusline at cursor-off >attrib2
  1252.              ." You MUST Load the expanded function set for that operation."
  1253.              eeol >norm beep 2 seconds cursor-on ;
  1254.  
  1255. defer shelp     ' notavail is shelp
  1256. defer exportx   ' notavail is exportx
  1257. defer excutx    ' notavail is excutx
  1258. defer importx   ' notavail is importx
  1259. defer pmenux    ' notavail is pmenux
  1260. defer kerr      ' beep is kerr
  1261.  
  1262.                 \ control key functiontable
  1263. : s^tbl         ( n1 --- )
  1264.                 exec:
  1265. \ @     A       B       C       D       E       F       G
  1266. kerr    lwrd    kerr    pdn     rchr    upln    rwrd    fdel
  1267. \ H     I       J       K       L       M       N       O
  1268. bdel    stab    kerr    kerr    lmset   nln     spltln  kerr
  1269. \ P     Q       R       S       T       U       V       W
  1270. kerr    kerr    pup     lchr    wdel    updt    itgl    sclup
  1271. \ X     Y       Z                                       F1
  1272. dnln    ldel    scldn   sesc    kerr    kerr    shoml   shelp ;
  1273.  
  1274.  
  1275.                 \ function key table
  1276. : sfuntbl       ( n1 --- )
  1277.                 exec:
  1278. \ A-9   A-0     A -     A =     CPGUP   133     134     135
  1279. kerr    kerr    kerr    kerr    kerr    kerr    kerr    kerr
  1280. \ 136   137     138     139     140     141     142     BACKSPACE
  1281. kerr    kerr    kerr    kerr    kerr    kerr    kerr    sbtab
  1282. \ A-Q   A-W     A-E     A-R     A-T     A-Y     A-U     A-I
  1283. kerr    wr->fl  kerr    kerr    tabset  lundel  wudel   kerr
  1284. \ A-O   A-P     154     155     156     157     A-A     A-S
  1285. pmenux  pmenux  kerr    kerr    kerr    kerr    kerr    kerr
  1286. \ A-D   A-F     A-G     A-H     A-J     A-K     A-L     167
  1287. kerr    kerr    kerr    kerr    kerr    tabxp   lmset   kerr
  1288. \ 168   169     170     171     A-Z     A-X     A-C     A-V
  1289. kerr    kerr    kerr    kerr    kerr    excutx  exportx importx
  1290. \ A-B   A-N     A-M     179     180     181     182     183
  1291. kerr    joinln  kerr    kerr    kerr    kerr    kerr    kerr
  1292. \ 184   185     186     F1      F2      F3      F4      F5
  1293. kerr    kerr    kerr    shelp   tscrn   smrk    bscrn   sgetl
  1294. \ F6    F7      F8      F9      F10     197     198     199
  1295. sloon   kerr    srepn   kerr    ^cc     kerr    kerr    kerr
  1296. \ 200   201     202     203     204     205     206     END
  1297. kerr    kerr    kerr    kerr    kerr    kerr    kerr    sendl
  1298. \ 208   209     210     211     SF1     SF2     SF3     SF4
  1299. kerr    kerr    kerr    kerr    kerr    kerr    kerr    kerr
  1300. \ SF5   SF6     SF7     SF8     SF9     SF10    CF1     CF2
  1301. kerr    sloob   kerr    repall  kerr    kerr    kerr    kerr
  1302. \ CF3   CF4     CF5     CF6     CF7     CF8     CF9     CF10
  1303. kerr    kerr    kerr    kerr    kerr    kerr    kerr    kerr
  1304. \ AF1   AF2     AF3     AF4     AF5     AF6     AF7     AF8
  1305. kerr    kerr    kerr    kerr    kerr    slooa   kerr    srepa
  1306. \ AF9   AF10    242     CLEFT   CRIGHT  CEND    CPGDN   CHOME
  1307. kerr    squt    kerr    lwrd    rwrd    send    kerr    shom
  1308. \ A-1   A-2     A-3     A-4     A-5     A-6     A-7     A-8
  1309. kerr    kerr    kerr    kerr    kerr    kerr    kerr    kerr ;
  1310.  
  1311. : ?controls     ( c1 --- c1 )   \ handle control characters
  1312.                 dup 32 <
  1313.                 if      0 swap s^tbl
  1314.                 then    ;
  1315.  
  1316. : ?functions    ( c1 --- c2 )   \ handle function characters
  1317.                 dup 127 >       \ they have values >127
  1318.                 if      128 - 0 swap sfuntbl
  1319.                 then    ;
  1320.  
  1321. : ?del          ( c1 --- )      \ char is delete key
  1322.                 dup 127 = if drop fdel 0 then    ;
  1323.  
  1324. : ?schr         ( c1 --- )      \ insert character if not a func
  1325.                 dup 0> if schr 0 then    ;
  1326.  
  1327. : doachar       ( c1 --- f1 )
  1328.                 ?controls ?functions ?del ?schr ;
  1329.  
  1330. ' doachar is doacharx
  1331.  
  1332. variable scrline
  1333.  
  1334. : check.shndl   ( --- )         \ verify shndl is in the hndls array
  1335.                 shndl @ hndls >=
  1336.                 shndl @ hndls maxnest + b/hcb - < and 0=
  1337.                                 \ is shndl within the hndls array?
  1338.                                   \ and not stacked up to last handle.
  1339.                 abort" We are out of handles!" ;
  1340.  
  1341. : find.line     ( --- )         \ Assumes we are starting on first line.
  1342.                 loadline @ 1000 u>
  1343.                 if      ." One moment..."
  1344.                 then
  1345.                 byte|line @     \ Are we going to a byte offset or a line#?
  1346.                 if      0 lastline @ 0 over min
  1347.                         ?do     i #linedata nip + dup loadline @  u>=
  1348.                                 if      i 1+ to.line leave
  1349.                                 then
  1350.                         loop    drop
  1351.                 else    loadline @ 1- 0 max maxlines min to.line
  1352.                         byte|line on    \ reset to byte offset
  1353.                 then    ;
  1354.  
  1355. : deferset      ( --- )         \ save current defered words, and reset them
  1356.                 @> keyfilter    is normfilter  ['] skeyfilter  is keyfilter
  1357.                 @> key up @ + @ is normkey     ['] statkey     is key
  1358.                 @> bgstuff      is normbgstuff ['] ?showstatus is bgstuff ;
  1359.  
  1360. : deferreset    ( --- )         \ restore the defered words old function.
  1361.                 @> normbgstuff is bgstuff
  1362.                 @> normkey     is key
  1363.                 @> normfilter  is keyfilter ;
  1364.  
  1365. : <reedit>      ( --- )         \ reenter edit of file
  1366.                 time-reset
  1367.                 check.shndl
  1368.                 savestate
  1369.                 2 lmargin !     132 rmargin !
  1370.                 edready @ 0= abort" No file to re-edit."
  1371.                 dark ?showfull drop ?change.bak
  1372.                 find.line
  1373.                 scrline @ curline 1+ min =: screenline
  1374.                 showscreen
  1375.                 begin   vstaton on showcur key doachar
  1376.                 until   restorestate ;
  1377.  
  1378. : reedit        ( --- )
  1379.                 deferset
  1380.                 <reedit>
  1381.                 deferreset ;
  1382.  
  1383. : <sed>         ( t1 --- )
  1384.                 deferset
  1385.                 dark
  1386.                 begin   close 0 1 at 28 ss
  1387.                         >attrib1 ." Tom's Sequential Editor" >norm
  1388.                         cr 0 3 at get     ( --- f1 )
  1389.                 while   sinit
  1390.                         ['] statfunc is showstat
  1391.                         edready on
  1392.                         <reedit>
  1393.                 repeat  deferreset ;
  1394.  
  1395. : esed          ( t1 --- )      \ entry point for sequential file editor.
  1396.                 0 loadline !
  1397.                 1 scrline ! <sed> ;
  1398.  
  1399. only forth definitions
  1400.  
  1401.